当BLOC中的流值更改时导航到新屏幕 [英] Navigating to a new screen when stream value in BLOC changes
问题描述
在Flutter中,当流的值更改时,我将如何调用Navigator.push?我已经尝试了下面的代码,但出现错误.
In Flutter how would I call Navigator.push when the value of a stream changes? I have tried the code below but get an error.
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
用于构建屏幕内容,而无其他内容.
You should not use StreamBuilder
to handle navigation.
StreamBuilder
is used to build the content of a screen and nothing else.
相反,您将必须收听流以手动触发副作用.这是通过使用StatefulWidget
并像这样覆盖initState
/dispose
来完成的:
Instead, you will have to listen to the stream to trigger side-effects manually. This is done by using a StatefulWidget
and overriding initState
/dispose
as such:
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
.
Note that if you're using an InheritedWidget
to obtain your stream (typically BLoC), you will want to use didChangeDependencies
instead of 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();
}
}
这篇关于当BLOC中的流值更改时导航到新屏幕的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!