Flutter:如何从StreamBuilder构造函数的回调中导航到另一个屏幕

3
我有一个启动画面和一个StreamBuilder,它会发出一个包含身份验证状态信息的状态。当认证状态已知时,我想要导航到登录页面或主页。但是当我编写像Navigator.of(context).pushReplacement(...)这样的代码时,我遇到了...
最初的回答: 在构建StreamBuilder时,调用了setState()或markNeedsBuild(),导致出现异常。这个Overlay widget不能被标记为需要构建,因为框架已经在构建widget了。只有当它的祖先之一正在构建时,才可以在构建阶段将widget标记为需要构建。此异常是允许的,因为框架会在构建父级widget之前构建子级widget,这意味着脏的子代始终会被构建。否则,在此构建阶段,框架可能不会访问此widget。在调用setState()或markNeedsBuild()的widget是:Overlay-[LabeledGlobalKey#e0460](state: OverlayState#ab1a5(entries:[OverlayEntry#4e962(opaque: false; maintainState: false), OverlayEntry#7656a(opaque: false; maintainState: true), OverlayEntry#1f86e(opaque: false; maintainState: false), OverlayEntry#05a15(opaque: false; maintainState: true)]))。而当前正在构建的widget是:StreamBuilder(dirty, state: _StreamBuilderBaseState>#f4346)。
我找到的唯一解决办法是使用Future(...).then(navigate)将导航安排在事件队列的末尾,但这很麻烦。是否有更好的解决方案?翻译成中文为:

我找到的唯一解决办法是使用Future(...).then(navigate)将导航安排在事件队列的末尾,但这很麻烦。是否有更好的解决方案?

2个回答

4
你可以在 build 方法外部监听你的流,并从那里重定向到另一个视图。
---- 编辑 ----
以下是实现方法示例:
@override
void initState() {
    super.initState();

    Future.delayed(Duration.zero, _verify);
}

void _verify() {
    final _myBloc = BlocProvider.getBloc<MyBloc>();

    _myBloc.myStream.listen((data) {
        // Redirect to another view, given your condition
        if (data) { 
            Navigator.of(context).pushNamed("my-new-route");
        }
    });
}

请记得保存从listen方法返回的StreamSubscription对象,这样你就可以在dispose()上取消订阅。


1
在我的情况下,这确实更有意义。我已经想出了一个方法,可以在“Consumer”小部件内创建一个流订阅,并在适当的时间处置它。 - nyarian
4
你的回答不完整,如果你提供一个例子会更好! - Shady Mohamed Sherif

1
我仍然不满意我的解决方案,但我使用了一个


if(snapshot.hasdata && snapshot.data.navigate) {
     Future.microtask(() => Navigator.of(context).push... );
   }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接