请帮助我理解为什么屏幕没有使用更新的数据重建。
这是最顶层的小部件,我用 StreamBuilder 包装了 MaterialApp:
class MyApp extends StatelessWidget {
final bloc = BlocSingleton();
@override
Widget build(BuildContext context) {
return StreamBuilder<String>(
stream: bloc.dataStream,
initialData: 'initial data',
builder: (context, snapshot) {
print('Stream updated with snapshot.data: ${snapshot.data}');
return MaterialApp(
routes: {
'/': (context) {
print('Home route activated with: ${snapshot.data}');
return Home(data: snapshot.data);
},
'/my_screen': (context) {
print('MyScreen route activated with: ${snapshot.data}');
return MyScreen(data: snapshot.data);
},
},
);
},
);
}
}
这是Home
屏幕,我有一个按钮可以转到MyScreen
:
class Home extends StatelessWidget {
final String data;
Home({this.data});
@override
Widget build(BuildContext context) {
print('Home builded');
return Scaffold(
appBar: AppBar(
title: Text('Home'),
actions: [
MaterialButton(
child: Text('to my_screen'),
textColor: Colors.white,
color: Colors.purple,
onPressed: () {
Navigator.of(context).pushNamed('/my_screen');
},
),
],
),
body: Container(
alignment: Alignment.center,
child: Text('$data'),
),
);
}
}
这是 MyScreen
屏幕,带有将更新的数据推送到流的按钮:
class MyScreen extends StatelessWidget {
final bloc = BlocSingleton();
final String data;
MyScreen({this.data});
@override
Widget build(BuildContext context) {
print('MyScreen builded');
return Scaffold(
appBar: AppBar(
title: Text('MyScreen'),
actions: [
MaterialButton(
child: Text('update stream'),
textColor: Colors.white,
color: Colors.purple,
onPressed: () {
bloc.dataSink.add('--- updated data ---');
},
),
],
),
body: Container(
alignment: Alignment.center,
child: Text('$data'),
),
);
}
}
所以从 Home
屏幕我按下按钮并转到 MyScreen
。
控制台输出为:
I/flutter (26700): Stream updated with snapshot.data: initial data
I/flutter (26700): Home route activated with: initial data
I/flutter (26700): Home builded
I/flutter (26700): MyScreen route activated with: initial data
I/flutter (26700): MyScreen builded
然后我按下按钮更新流并在控制台中得到输出:
I/flutter (26700): Stream updated with snapshot.data: --- updated data ---
I/flutter (26700): Home route activated with: initial data
I/flutter (26700): Home builded
I/flutter (26700): MyScreen route activated with: initial data
I/flutter (26700): MyScreen builded
如您所见,屏幕使用先前数据重建:“初始数据”,但未使用更新数据重建:“--- 更新数据 ---”。
我知道屏幕可以是 StatefulWidget-s,当屏幕从堆栈中弹出时,我们可以将值返回到前一个屏幕并在那里调用 setState
来重建它。但感觉这不是最好的方法。