How to change title of main.dart AppBar in it's child programmatically? How to change title of main.dart AppBar in it's child programmatically? dart dart

How to change title of main.dart AppBar in it's child programmatically?


Have a BLoC for app properties in app_properties_bloc.dart

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

Use stream builder in AppBar like this:

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

Use this to update title on button's onPressed()

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


Just in case you are changing only the title of Scaffold then this will work.

I am creating a DefaultScaffold with the title each screen provides. Here the code will show the MainPage and two other pages which have the same AppBar with changed titles.

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

Note: This is a simple workaround and may not be the best way to do this.


You can accomplish updating the state of the parent from a child by using a callback function.

Parent Class:

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

Child Class

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

Reference: