如何以编程方式更改main.dart AppBar的子标题?

时间:2019-04-18 03:53:26

标签: dart flutter appbar

我在AppBar中有一个main.dart,我想将其定义为孩子的主要孩子,但是我想更改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);
          },
        ),
      ),
    );
  }
}

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

4 个答案:

答案 0 :(得分:1)

app_properties_bloc.dart中拥有应用属性的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();
  }
}

像这样在AppBar中使用流生成器:

AppBar(
   title: StreamBuilder<Object>(
       stream: appBloc.titleStream,
       initialData: "Main Dart",
       builder: (context, snapshot) {
           return Text(snapshot.data);
       }
   ),
),

使用它来更新按钮的onPressed()上的标题

onPressed: () {
    appBloc.updateTitle('new title');
},

答案 1 :(得分:1)

仅在您仅更改Scaffold的标题的情况下,这才起作用。

我正在创建一个DefaultScaffold,其标题由每个屏幕提供。此处的代码将显示MainPage和其他两个页面,它们具有相同的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"));
  }
}

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

答案 2 :(得分:0)

您可以通过使用回调函数来从parent更新child的状态。

父类:

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;
    });
  }
}

儿童班


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");
          },
        )
      ],
    );
  }
}

参考:

答案 3 :(得分:0)

使用ValueListenableBuilder是一个选项。

使用实例变量

String appTitle;

然后按照以下代码段设置应用栏:

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

之后,您可以简单地在另一个类中设置appTitle.value。标题也会更改,因为它会监听该值。

appTitle.value = "Home Screen";