Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/flutter/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何更改其中main.dart AppBar的标题';以编程方式创建子对象?_Dart_Flutter_Appbar - Fatal编程技术网

如何更改其中main.dart AppBar的标题';以编程方式创建子对象?

如何更改其中main.dart AppBar的标题';以编程方式创建子对象?,dart,flutter,appbar,Dart,Flutter,Appbar,我在main.dart中有一个AppBar,我想在它的子页面上将它定义为primary,但是当我在子页面上时,我想更改AppBar本身的标题,我如何才能正确地做到这一点 void main() => runApp(MyApp()); class MyApp extends StatelessWidget{ @override Widget build(BuildContext context) { return MaterialApp( title: "Flu

我在
main.dart中有一个
AppBar
,我想在它的子页面上将它定义为primary,但是当我在子页面上时,我想更改
AppBar
本身的标题,我如何才能正确地做到这一点

void main() => runApp(MyApp());

class MyApp extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "Flutter App",
      theme: ThemeData(
        primaryColor: Colors.cyan,
        brightness: Brightness.dark
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text("Main Dart"),
        ),
        body: HomeScreen(),
      ),
      routes: <String, WidgetBuilder>{
        '/homeScreen': (buildContext)=>HomeScreen(),
        '/second': (buildContext)=>Second() 
      },
    );
  }
}

//HomeScreen or Second Widget on different dart file

class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    //here I want to change the title of Main Dart to HomeScreen
    return Container(
      child: Center(
        child: FlatButton(
          child: new Text("Home screen"),
          onPressed: (){
            Route route = MaterialPageRoute(builder: (context) => Second());
            Navigator.push(context, route);
          },
        ),
      ),
    );
  }
}
void main()=>runApp(MyApp());
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回材料PP(
标题:“颤振应用程序”,
主题:主题数据(
primaryColor:Colors.cyan,
亮度:亮度。暗
),
家:脚手架(
appBar:appBar(
标题:文本(“主省道”),
),
主体:主屏幕(),
),
路线:{
“/homeScreen”:(buildContext)=>homeScreen(),
“/second”:(buildContext)=>second()
},
);
}
}
//不同dart文件上的主屏幕或第二个小部件
类主屏幕扩展无状态小部件{
@凌驾
小部件构建(构建上下文){
//这里我想把主飞镖的标题改成主屏幕
返回容器(
儿童:中心(
孩子:扁平按钮(
子项:新文本(“主屏幕”),
已按下:(){
路由=MaterialPage路由(生成器:(上下文)=>Second());
推送(上下文、路线);
},
),
),
);
}
}

或者我需要在每个屏幕中放置
Scaffold(appBar:appBar(…),…)
?这是最好的方法?

app\u properties\u BLoC.dart中为app属性创建一个BLoC

final appBloc = AppPropertiesBloc();

class AppPropertiesBloc{
  StreamController<String> _title = StreamController<String>();

  Stream<String> get titleStream => _title.stream;

  updateTitle(String newTitle){
    _title.sink.add(newTitle);
  }

  dispose() {
    _title.close();
  }
}

如果你只是更改脚手架的名称,那么这将起作用

我正在创建一个带有每个屏幕提供的标题的
DefaultScaffold
。在这里,代码将显示
主页
和其他两个具有相同
AppBar
且标题已更改的页面

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(initialRoute: 'home', routes: <String, WidgetBuilder>{
      'home': (context) => SOMain(),
      '/secondPage': (context) => DefaultScaffold("Second Screen", SOSecond()),
      '/thirdPage': (context) => DefaultScaffold("Third Screen", SOThird()),
    });
  }
}

class DefaultScaffold extends StatelessWidget {
  String title;
  Widget body;

  DefaultScaffold(this.title, this.body);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(title),
      ),
      body: body,
    );
  }
}

class SOMain extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return DefaultScaffold(
      "Main Screen",
      Center(
        child: RaisedButton(
            child: Text("Go to second screen"),
            onPressed: () {
              Navigator.pushNamed(context, '/secondPage');
            }),
      ),
    );
  }
}

class SOSecond extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: RaisedButton(
        child: Text("Go the 3rd screen"),
        onPressed: () => Navigator.pushNamed(context, "/thirdPage"),
      ),
    );
  }
}

class SOThird extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(child: Text("You are on last screen"));
  }
}
void main(){
runApp(MyApp());
}
类MyApp扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回物料应用(初始路线:“主”,路线:{
“home”:(上下文)=>SOMain(),
“/secondPage”:(上下文)=>DefaultScaffold(“第二个屏幕”,SOSecond()),
“/thirdPage”:(上下文)=>DefaultScaffold(“第三屏”,SOThird()),
});
}
}
类DefaultScaffold扩展了无状态小部件{
字符串标题;
控件体;
DefaultScaffold(此标题,此正文);
@凌驾
小部件构建(构建上下文){
返回脚手架(
appBar:appBar(
标题:文本(标题),
),
身体:身体,,
);
}
}
类SOMain扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回默认脚手架(
“主屏幕”,
居中(
孩子:升起按钮(
子项:文本(“转到第二个屏幕”),
已按下:(){
Navigator.pushNamed(上下文“/secondPage”);
}),
),
);
}
}
类SOSecond扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回中心(
孩子:升起按钮(
子:文本(“转到第三个屏幕”),
onPressed:()=>Navigator.pushNamed(上下文“/thirdPage”),
),
);
}
}
类SOThird扩展了无状态小部件{
@凌驾
小部件构建(构建上下文){
返回中心(子:文本(“您在最后一个屏幕上”);
}
}

注意:这是一个简单的解决方法,可能不是最好的解决方法。

您可以使用回调函数从
子项
更新
父项
的状态

父类:

import 'package:flutter/material.dart';

class Parent extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return ParentState();
  }
}

class ParentState extends State<Parent> {

  String title = "Old Title";

  @override
  Widget build(BuildContext context) {

    return new Scaffold(
        appBar: new AppBar(
        title: new Text(title),
      ),
      body: DaysFragmentView(onTitleSelect: (String value) {
            setTitle(value);
        }
      ),
    );

  }

  void setTitle(String value) {
    setState(() {
      title = value;
    });
  }
}

导入“包装:颤振/材料.省道”;
类父级扩展StatefulWidget{
@凌驾
状态createState(){
返回ParentState();
}
}
类ParentState扩展了状态{
字符串title=“旧标题”;
@凌驾
小部件构建(构建上下文){
归还新脚手架(
appBar:新的appBar(
标题:新文本(标题),
),
正文:DaysFragmentView(onTitleSelect:(字符串值){
设置标题(值);
}
),
);
}
void setTitle(字符串值){
设置状态(){
标题=价值;
});
}
}
儿童班


typedef TitleCallback = void Function(Title color);

class DaysFragmentView extends StatelessWidget {
  const DaysFragmentView({this.onTitleSelect});

  final TitleCallback onTitleSelect;

  @override
  Widget build(BuildContext context) {
    return Row(
      children: <Widget>[
        RaisedButton(
          child: Text('One'),
          onPressed: () {
            onTitleSelect("TITLE ONE");
          },
        ),
        RaisedButton(
          child: Text('Two'),
          onPressed: () {
            onTitleSelect("TITLE TWO");
          },
        )
      ],
    );
  }
}

typedef TitleCallback=无效函数(标题颜色);
类DaysFragmentView扩展了无状态小部件{
const DaysFragmentView({this.onTitleSelect});
最终标题回拨字幕选择;
@凌驾
小部件构建(构建上下文){
返回行(
儿童:[
升起的按钮(
子项:文本(“一”),
已按下:(){
onTitleSelect(“标题一”);
},
),
升起的按钮(
child:Text('Two'),
已按下:(){
onTitleSelect(“标题二”);
},
)
],
);
}
}
参考:


使用ValueListenableBuilder是一种选择

使用实例变量

String appTitle;
然后将应用程序栏设置为以下方框:

appBar: AppBar(
          ValueListenableBuilder<String>(
          valueListenable: appTitle,
          builder: (context, value, child) {
            return Text(appTitle.value);
          },
        ),

你能上第二节课吗?你在每节课上都使用脚手架吗route@Doc我想在每一条路线上都避免使用脚手架,所以我的第二条路线与主屏幕上的相同,是否完全不可避免地会有脚手架?@doc我脑海中的主要问题是“为什么我需要在每一页上放置
Scaffold
,只是为了更改
appBar
的标题?”这只是我作为一个颤振开发新手的问题,任何建议都是值得欢迎的,这似乎是一个合法的疑问;研究它。为什么它看起来像是用机关枪杀死一只苍蝇?对于一个简单的任务来说太多了。我认为颤振会减少代码:(这是因为你只有一个属性像这样变化,而对于那一个属性,你觉得它不值得。但是假设你有多个像这样的属性,你就会感觉不一样。使用StreamBuilder更新数据是有效的,因为它只会生成需要更新的小部件。是的,我也这么认为,如果有一大堆的东西,但是
String appTitle;
appBar: AppBar(
          ValueListenableBuilder<String>(
          valueListenable: appTitle,
          builder: (context, value, child) {
            return Text(appTitle.value);
          },
        ),
appTitle.value = "Home Screen";