我有一个启动屏幕和一个StreamBuilder
,它发出包含身份验证状态信息的状态。当身份验证状态已知时,我希望导航到登录页或主页。但是当我写一些类似Navigator.of(context).pushReplacement(...)
的东西时
I/flutter (2058年):由小部件库╞═══════════════════════════════════════════════════════════I/flutter (2058)捕获的══╡异常:在构建StreamBuilder时抛出以下断言(脏、状态:I/颤振( 2058):_StreamBuilderBaseState>#f4346):I/flutter ( 2058):setState()或markNeedsBuild()。I/flutter ( 2058):不能将此覆盖小部件标记为需要构建,因为框架已经在I/flutter ( 2058):构建小部件的过程中。小部件可以标记为需要在构建阶段I/颤振(2058)期间构建:只有当其祖先之一正在构建时。允许此异常是因为框架I/flutter ( 2058):在子级之前构建父部件,这意味着将始终构建脏子代。I/flutter ( 2058):否则,框架可能不会在此构建阶段访问此小部件。I/颤振( 2058):调用setState()或markNeedsBuild()的小部件是: I/flutter ( 2058):Overlay-LabeledGlobalKey#e0460 I/flutter ( 2058):当前正在构建的违规调用时构建的部件是: I/flutter ( 2058):StreamBuilder(脏,状态:_StreamBuilderBaseState>#f4346) I/flutter ( 2058):I/flutter ( 2058):当抛出异常时,这是堆栈:i/LabeledGlobalKey#e0460( 2058):#0 Element.markNeedsBuild。(package:flutter/src/widgets/framework.dart:3503:11) I/颤振(2058年):#1 Element.markNeedsBuild (package:flutter/src/widgets/overlay.dart:346:5) I/颤振(2058年):#2 State.setState (package:flutter/src/widgets/framework.dart:1133:14) I/颤振(2058年):#3 OverlayState.insertAll (package:flutter/src/widgets/overlay.dart:346:5)I/颤振(2058年):#4 (package:flutter/src/widgets/routes.dart:43:24) I/颤振(2058年):#5 TransitionRoute.install (package:flutter/src/widgets/routes.dart:180:11) I/颤振(2058年):#6 ModalRoute.install (package:flutter/src/widgets/routes.dart:895:11) I/颤振(2058年):#7 NavigatorState.pushReplacement (软件包:flutter/src/小部件/小部件)I/颤振(2058年):#8 (package:map_chat/application/navigation.dart:75:27) I/颤振(2058年):#9 _SignInPage.replace (package:map_chat/application/navigation.dart:67:5) I/颤振(2058年):#10 Roadmap.replace (package:map_chat/application/navigation.dart:25:18) I/颤振( 2058):#11_SplashPageState._buildPageBasedOnAuthenticationState (包:map_chat/feature/spash.dart:52:19)i/颤振(2058年):#12 _SplashPageState._buildSplashScreen (包:map_chat/_SplashPageState._buildSplashScreen/spash.dart:40:11)i/颤振(2058年):#13 _SplashPageState._buildPage。(软件包:map_chat/ (package:flutter/src/widgets/async.dart:425:74) /spash.dart:27:18) I/颤振( 2058):#14 StreamBuilder.build (package:flutter/src/widgets/framework.dart:3825:27) I/颤振( 2058):#15 _StreamBuilderBaseState.build (package:flutter/src/widgets/async.dart:125:48) I/颤振( 2058):#16 StatefulElement.build (package:flutter/src/widgets/framework.dart:3825:27)I/颤振( 2058):#17 (package:flutter/src/widgets/framework.dart:3739:15) I/颤振( 2058):#18 Element.rebuild (package:flutter/src/widgets/framework.dart:3565:5) I/颤振( 2058):#19 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2278:33) I/颤振( 2058):#20 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding&WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:700:20) I/颤振(2058年):#21 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:286:5) I/颤振( 2058):#22 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:1012:15) I_WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:952:9) (2058年):#23 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.scheduleWarmUpFrame. I/颤振(2058年):#24 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.scheduleWarmUpFrame.(package:flutter/src/scheduler/binding.dart:773:7) I/颤振(2058年):#33 _Timer._runTimers (飞镖:隔离-补丁/计时器_ _Timer._handleMessage :382:19)I/颤振( 2058):#34 _Timer._handleMessage(飞镖:隔离-补丁/定时器__Timer._handleMessage:416:5)I/颤振( 2058):#35 _RawReceivePortImpl._handleMessage (飞镖:隔离-补丁/隔离_patch:171:12) I/颤振( 2058):(从包省道中删除8帧:异步和包飞镖:异步补丁)
我找到的唯一解决办法是使用Future(...).then(navigate)
将导航安排到事件队列的末尾,但这是病态的。这里有足够的解决办法吗?
发布于 2019-05-14 18:23:56
您可以在构建方法之外侦听您的流并从那里重定向到另一个视图。
编辑--编辑
这是你如何做到这一点的一个例子:
@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
方法返回的listen
对象,这样就可以取消dispose()
上的订阅。
发布于 2020-03-12 23:37:40
我仍然不满意我的解决方案,但我使用了
if(snapshot.hasdata && snapshot.data.navigate) {
Future.microtask(() => Navigator.of(context).push... );
}
https://stackoverflow.com/questions/56116766
复制相似问题