dart - 嵌套未来中的导航
问题描述
编辑:问题完全按照我在这个新问题主题中的要求解决:
老问题:
这是我的引导屏幕,我想创建条件导航,但据我了解,FutureBuilder 没有导航逻辑。
这是我的启动屏幕构建方法:
@override
Widget build(BuildContext context) {
return Material(
child: ScopedModelDescendant<MainModel>(
builder: (BuildContext context, Widget child, MainModel model) {
return FutureBuilder(
future: model.bootUp(),
builder: (context, bootSnapshot) {
print('====${bootSnapshot.data} is SNAPSHOT DATA====');
return !bootSnapshot.hasData
? _buildSplash(context)
: bootSnapshot.data
? FutureBuilder(
future: model.fetchAll(model.tempUser),
builder: (context, dataSnapshot) {
return !dataSnapshot.hasData
? _buildSplash(context)
: Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (context) => HomePage()),
);
})
: Navigator.of(context).pushReplacement(
MaterialPageRoute(
builder: (context) => FirstScreen(),
),
);
},
);
},
),
);
}
正如您在代码中看到的,首先我使用异步方法检查用户之前是否登录,然后如果他之前登录,那么我正在获取与他相关的数据,一旦获取完成我想导航到用户主页。
错误日志:
I/flutter (24348): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter (24348): The following assertion was thrown building FutureBuilder<String>(dirty, state:
I/flutter (24348): _FutureBuilderState<String>#e0594):
I/flutter (24348): setState() or markNeedsBuild() called during build.
I/flutter (24348): This Overlay widget cannot be marked as needing to build because the framework is already in the
I/flutter (24348): process of building widgets. A widget can be marked as needing to be built during the build phase
I/flutter (24348): only if one of its ancestors is currently building. This exception is allowed because the framework
I/flutter (24348): builds parent widgets before children, which means a dirty descendant will always be built.
I/flutter (24348): Otherwise, the framework might not visit this widget during this build phase.
I/flutter (24348): The widget on which setState() or markNeedsBuild() was called was:
I/flutter (24348): Overlay-[LabeledGlobalKey<OverlayState>#c7eb6](state: OverlayState#953bd(entries:
I/flutter (24348): [OverlayEntry#b9486(opaque: false; maintainState: false), OverlayEntry#af059(opaque: false;
I/flutter (24348): maintainState: true), OverlayEntry#81d00(opaque: false; maintainState: false),
I/flutter (24348): OverlayEntry#be7c4(opaque: false; maintainState: true)]))
I/flutter (24348): The widget which was currently being built when the offending call was made was:
I/flutter (24348): FutureBuilder<String>(dirty, state: _FutureBuilderState<String>#e0594)
I/flutter (24348):
I/flutter (24348): When the exception was thrown, this was the stack:
I/flutter (24348): #0 Element.markNeedsBuild.<anonymous closure> (package:flutter/src/widgets/framework.dart:3485:11)
I/flutter (24348): #1 Element.markNeedsBuild (package:flutter/src/widgets/framework.dart:3511:6)
I/flutter (24348): #2 State.setState (package:flutter/src/widgets/framework.dart:1146:14)
I/flutter (24348): #3 OverlayState.insertAll (package:flutter/src/widgets/overlay.dart:301:5)
I/flutter (24348): #4 OverlayRoute.install (package:flutter/src/widgets/routes.dart:43:24)
I/flutter (24348): #5 TransitionRoute.install (package:flutter/src/widgets/routes.dart:185:11)
I/flutter (24348): #6 ModalRoute.install (package:flutter/src/widgets/routes.dart:861:11)
I/flutter (24348): #7 NavigatorState.pushReplacement (package:flutter/src/widgets/navigator.dart:1618:14)
I/flutter (24348): #8 BootScreen.build.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:mostadam/pages/boot_screen.dart:49:49)
I/flutter (24348): #9 _FutureBuilderState.build (package:flutter/src/widgets/async.dart)
I/flutter (24348): #10 StatefulElement.build (package:flutter/src/widgets/framework.dart:3809:27)
I/flutter (24348): #11 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3721:15)
I/flutter (24348): #12 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5)
I/flutter (24348): #13 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2286:33)
I/flutter (24348): #14 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding&WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:676:20)
I/flutter (24348): #15 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:219:5)
I/flutter (24348): #16 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:990:15)
I/flutter (24348): #17 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:930:9)
I/flutter (24348): #18 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:842:5)
I/flutter (24348): #19 _invoke (dart:ui/hooks.dart:154:13)
I/flutter (24348): #20 _drawFrame (dart:ui/hooks.dart:143:3)
解决方案
编辑:下面的答案很老了。真正的解决方案是使用WidgetsBinding
. 在snapshot.hasData
条件内,把这个方法:
WidgetsBinding.instance!.addPostFrameCallback((_) {
Navigator.of(context)
.pushReplacement(MaterialPageRoute(builder: (context) {
if (~snapshot condition~) {
return HomePage();
}
return FirstPage();
}));
});
addPostFrameCallback
是在build
方法执行完成后立即执行一次的方法。
Anmol已经回答了评论中的问题。
解决方法很简单,只需返回您要导航的页面即可。但对于一些罕见的特定情况,IMO 是不够的。我希望我们对未来的更新有更好的选择。
解决方案:
代替
Navigator.of(context).pushReplacement( MaterialPageRoute(builder: (context) => HomePage();
简单的说:
return HomePage();
相同的:
return FirstScreen();
推荐阅读
- python - 使用 sklearn 如何计算文档和查询之间的 tf-idf 余弦相似度?
- oracle - 由于某种原因,原定从钦奈到班加罗尔的巴士被推迟了 5 天
- terraform - 来自模块中变量的动态供应商
- kubernetes - Kubernetes:无法更改部署策略
- javascript - 将 Json 转换为 svg
- shell - 什么鱼相当于 bash if/then/else/fi 块?
- android - 如何将背景图像设置为按钮但仍像普通按钮一样工作(带效果)?
- dns - 由于找不到 etcd 本地成员,etcd 无法设置集群
- amazon-web-services - 闲置时,带有 Lambda 的 API 网关在第一次调用时返回 404?
- python - 如何让 Keras 模型预测的文本回到单词列表中?