2

我有一个启动屏幕和一个StreamBuilder发出包含有关身份验证状态信息的状态的状态。当身份验证状态已知时,我想导航到登录页面或主页。但是当我写出Navigator.of(context).pushReplacement(...)我得到的东西时

我/颤振(2058):══╡小部件库发现异常╞═════════════════════════════════════════════ ═════════════════════════ I/flutter(2058):构建 StreamBuilder(脏,状态:I/flutter(2058)) : _StreamBuilderBaseState>#f4346): I/flutter (2058): setState() 或 markNeedsBuild() 在构建期间调用。I/flutter(2058):这个Overlay widget不能被标记为需要构建,因为框架已经在I/flutter(2058):构建widget的过程中。可以在构建阶段 I/flutter ( 2058 ) 期间将小部件标记为需要构建:仅当其祖先之一当前正在构建时。这个例外是允许的,因为框架 I/flutter ( 2058): 在子级之前构建父级小部件,这意味着将始终构建一个肮脏的后代。我/颤动(2058):否则,在此构建阶段,框架可能不会访问此小部件。I/flutter(2058):调用 setState() 或 markNeedsBuild() 的小部件是:I/flutter(2058):Overlay-[LabeledGlobalKey#e0460](状态:OverlayState#ab1a5(条目:I/flutter(2058) ): [OverlayEntry#4e962(opaque: false; maintainState: false), OverlayEntry#7656a(opaque: false; I/flutter (2058): maintainState: true), OverlayEntry#1f86e(opaque: false; maintainState: false), I /flutter (2058): OverlayEntry#05a15(opaque: false; maintainState: true)])) I/flutter (2058): 发出违规调用时当前正在构建的小部件是:I/flutter (2058): StreamBuilder(dirty, state: _StreamBuilderBaseState>#f4346) I/flutter (2058): I/flutter (2058): 当异常被抛出时,这是堆栈: I/flutter (2058): #0 Element.markNeedsBuild。(package:flutter/src/widgets/framework.dart:3503:11) I/flutter (2058): #1 Element.markNeedsBuild (package:flutter/src/widgets/framework.dart:3529:6) I/flutter ( 2058): #2 State.setState (package:flutter/src/widgets/framework.dart:1133:14) I/flutter (2058): #3 OverlayState.insertAll (package:flutter/src/widgets/overlay.dart: 346:5) I/flutter (2058): #4 OverlayRoute.install (package:flutter/src/widgets/routes.dart:43:24) I/flutter (2058): #5 TransitionRoute.install (package:flutter/ src/widgets/routes.dart:180:11) I/flutter (2058): #6 ModalRoute.install (package:flutter/src/widgets/routes.dart:895:11) I/flutter (2058): #7 NavigatorState.pushReplacement (package:flutter/src/widgets/navigator.dart:1799:14) I/flutter (2058): #8 _replace (package: map_chat/application/navigation.dart:75:27) I/flutter (2058): #9 _SignInPage.replace (package:map_chat/application/navigation.dart:67:5) I/flutter (2058): #10 路线图。替换 (package:map_chat/application/navigation.dart:25:18) I/flutter (2058): #11 _SplashPageState._buildPageBasedOnAuthenticationState (package:map_chat/feature/splash.dart:52:19) I/flutter (2058): #12 _SplashPageState._buildSplashScreen (package:map_chat/feature/splash.dart:40:11) I/flutter (2058): #13 _SplashPageState._buildPage。(package:map_chat/feature/splash.dart:27:18) I/flutter (2058): #14 StreamBuilder.build (package:flutter/src/widgets/async.dart:425:74) I/flutter (2058) : #15 _StreamBuilderBaseState.build (package:flutter/src/widgets/async.dart:125:48) I/flutter (2058): #16 StatefulElement.build (package: flutter/src/rendering/binding.dart:286:5) I/flutter (2058): #22 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1012:15) I/flutter (2058): #23 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:952:9) I/flutter (2058): #24 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.scheduleWarmUpFrame。(package:flutter/src/scheduler/binding.dart:773:7) I/flutter (2058): #33 _Timer._runTimers (dart:isolate-patch/timer_impl.dart:382:19) I/flutter (2058) : #34 _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:416:5) I/flutter (2058):

我发现的唯一解决方法是将导航安排到事件队列的末尾,Future(...).then(navigate)但这很糟糕。这是一个足够的解决方案吗?

4

2 回答 2

3

您可以在 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");
        }
    });
}

只要记住保存方法StreamSubscription返回的对象listen,这样你就可以取消订阅dispose()

于 2019-05-14T18:23:56.597 回答
1

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

if(snapshot.hasdata && snapshot.data.navigate) {
     Future.microtask(() => Navigator.of(context).push... );
   }
于 2020-03-12T23:37:40.467 回答