在Flutter中,当流的值发生变化时,如何调用Navigator.push?我已经尝试了下面的代码,但得到了一个错误.
StreamBuilder( stream: bloc.streamValue,builder: (BuildContext context,AsyncSnapshot<int> snapshot) { if (snapshot.hasData && snapshot.data == 1) { Navigator.push( context,MaterialPageRoute(builder: (context) => SomeNewScreen()),); } return Text(""); });
解决方法
您不应该使用StreamBuilder来处理导航.
StreamBuilder用于构建屏幕内容而不是其他内容.
StreamBuilder用于构建屏幕内容而不是其他内容.
相反,您将必须侦听流以手动触发副作用.这是通过使用StatefulWidget并重写initState / dispose来完成的:
class Example extends StatefulWidget { final Stream<int> stream; const Example({Key key,this.stream}) : super(key: key); @override ExampleState createState() => ExampleState(); } class ExampleState extends State<Example> { StreamSubscription _streamSubscription; @override void initState() { super.initState(); _listen(); } @override void didUpdateWidget(Example oldWidget) { super.didUpdateWidget(oldWidget); if (oldWidget.stream != widget.stream) { _streamSubscription.cancel(); _listen(); } } void _listen() { _streamSubscription = widget.stream.listen((value) { Navigator.pushNamed(context,'/someRoute/$value'); }); } @override void dispose() { _streamSubscription.cancel(); super.dispose(); } @override Widget build(BuildContext context) { return Container(); } }
请注意,如果您使用InheritedWidget来获取流(通常是BLoC),则需要使用didChangeDependencies而不是initState / didUpdateWidget.
这导致:
class Example extends StatefulWidget { @override ExampleState createState() => ExampleState(); } class ExampleState extends State<Example> { StreamSubscription _streamSubscription; Stream _prevIoUsStream; void _listen(Stream<int> stream) { _streamSubscription = stream.listen((value) { Navigator.pushNamed(context,'/someRoute/$value'); }); } @override void didChangeDependencies() { super.didChangeDependencies(); final bloc = MyBloc.of(context); if (bloc.stream != _prevIoUsStream) { _streamSubscription?.cancel(); _prevIoUsStream = bloc.stream; _listen(bloc.stream); } } @override void dispose() { _streamSubscription.cancel(); super.dispose(); } @override Widget build(BuildContext context) { return Container(); } }