屏幕之间的Flutter streambuilder



我是Flutter的新手,我用streambuilder实现了block架构。我创建了两个页面,只有一个按钮可以改变我的背景颜色。所有这些页面都在听流来改变背景色,但当我在第一页上改变时,第二页就没有了。但如果1页决定更改,我希望我的所有应用程序都能更改

我需要初始化一个我的2个屏幕使用的singleton块吗?因为目前每个屏幕都会初始化自己的区块下面是一个1页的例子(第二页相同(

class Test extends StatelessWidget {
final ColorBloc _bloc = ColorBloc();
@override
Widget build(BuildContext context) {
return StreamBuilder<Response<ColorResponse>>(
stream: _bloc.stream,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Scaffold(
appBar: AppBar(
title: Text('First Route clicked'),
),
backgroundColor: snapshot.data.data.color,
body: new Center(
child: new InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Act2()),
);
}, // Handle your callback
child: Ink(height: 100, width: 100, color: Colors.blue),
)),
floatingActionButton: FloatingActionButton(
onPressed: () {
_bloc.changeColor(Colors.yellow);
},
child: Icon(Icons.navigation),
backgroundColor: Colors.green,
));
}
return Scaffold(
appBar: AppBar(
title: Text('First Route'),
),
body: Center(
child: new InkWell(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Act2()),
);
}, // Handle your callback
child: Ink(height: 200, width: 200, color: Colors.red))),
floatingActionButton: FloatingActionButton(
onPressed: () {
_bloc.changeColor(Colors.yellow);
},
child: Icon(Icons.navigation),
backgroundColor: Colors.green,
));
},
);
}
}

要在一个区块触发事件时更改所有屏幕的状态,可以使用多个StreamBuilder,但所有这些都需要监听触发事件的区块。你可以试试这两种方法:

  • 将块作为参数传递到第二个屏幕
class Test extends StatelessWidget {
final ColorBloc _bloc = ColorBloc();
@override
Widget build(BuildContext context) {
return StreamBuilder<Response<ColorResponse>>(
// ... other lines
body: new Center(
child: new InkWell(
onTap: () {
// Pass your bloc to the 2nd screen
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Act2(bloc: _bloc)),
);
}, 
// ... other lines
  • 使用诸如provider包之类的包将区块向下传递到树中。在您的第一个屏幕中,您可以执行以下操作:
class Test extends StatelessWidget {
final ColorBloc _bloc = ColorBloc();
@override
Widget build(BuildContext context) {
// Use Provider to provide the bloc down the widget tree
return Provider(
create: (_) => _bloc,
child: StreamBuilder<Response<ColorResponse>>(

// ... other lines

然后在第二个屏幕(我假设是Act2(((中,您从提供程序获得ColorBloc:


class Act2 extends StatefulWidget {
@override
_Act2State createState() => _Act2State();
}
class _Act2State extends State<Act2> {
ColorBloc _colorBloc;
@override
void didChangeDependencies() {
// Get the bloc in the 1st page
_colorBloc = Provider.of<ColorBloc>(context);
super.didChangeDependencies();
}
@override
Widget build(BuildContext context) {
return StreamBuilder<Response<ColorResponse>>(
// Use the bloc like in the 1st page
stream: _colorBloc.stream, 
builder: (context, snapshot) {
if (snapshot.hasData) {
// ... other lines

小提示:使用StreamBuilder时,无需重复代码即可启动值。由于我不知道你的Response对象的结构,我以Response(ColorResponse(color: Colors.green))为例:

// ... other lines
@override
Widget build(BuildContext context) {
return Provider(
create: (_) => _bloc,
child: StreamBuilder<Response<ColorResponse>>(
// Initiate your data here
initialData: Response(ColorResponse(color: Colors.green)), 
stream: _bloc.stream,
builder: (context, snapshot) {
if (snapshot.hasData) {
return Scaffold(
appBar: AppBar(
title: Text('First Route clicked'),
),
backgroundColor: snapshot.data.data.color,
// ... other lines
}
// Don't need to copy the above code block for the case when the data is not streamed yet
return Container(child: Center(child: CircularProgressIndicator()));
},
),
);
}

相关内容

  • 没有找到相关文章

最新更新