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: