嵌套未来中的导航 [英] Navigation inside Nested Future
问题描述
编辑:完全按照我想要的新问题主题解决问题:
旧问题:
这是我的引导屏幕,我想创建条件导航,但是据我了解,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}是快照数据====');
返回!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):W小部件库引起的异常CA ══════════════════════════════════════════════════ ══════
I / flutter(24348):构建断言FutureBuilder< String>时引发了以下断言(脏,状态:
I / flutter(24348):_ FutureBuilderState< String>#e0594) :
I / flutter(24348):在构建过程中调用了setState()或markNeedsBuild()。
I / flutter(24348):无法将该覆盖小部件标记为需要构建,因为该框架已在
I / flutter(24348):构建小部件的过程中。可以将一个小部件标记为需要在构建阶段
I / flutter(24348):仅当其祖先中的一个正在构建时。因为框架
I / flutter(24348):会在子代之前构建父窗口小部件,所以会允许该异常,这意味着将始终构建脏后代。
I / flutter(24348):否则,框架在此构建阶段可能不会访问此小部件。
I / flutter(24348):调用了setState()或markNeedsBuild()的小部件为:
I / flutter(24348):Overlay- [LabeledGlobalKey< OverlayState>#c7eb6](状态: OverlayState#953bd(条目:
I / flutter(24348):[OverlayEntry#b9486(不透明:false; maintainState:false),OverlayEntry#af059(不透明:false;
I / flutter(24348): maintainState:true),OverlayEntry#81d00(不透明:false; maintainState:false),
I / flutter(24348):OverlayEntry#be7c4(opaque:false; maintainState:true)]))
I / flutter(24348):在发出违规呼叫时当前正在构建的小部件为:
I / flutter(24348):FutureBuilder< String>(脏,状态:_FutureBuilderState< String>#e0594)
I / flutter(24348):
I / flutter(24348):引发异常时,堆栈为:
I / flutter(24348):#0 Element.markNeedsBuild。 >关闭(软件包:flutter / src / widgets / framework.dart:3485:11)
I / flutter(24348):#1 Element.markNeedsBuild(软件包: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(软件包:flutter / src / widgets / overlay.dart:301:5)
I / flutter(24348):#4 OverlayRoute.install(软件包:flutter / src / widgets / routes.dart:43:24)
I / flutter(24348):#5 TransitionRoute.install(软件包:flutter / src / widgets / routes.dart:185:11)
I / flutter(24348):#6 ModalRoute.install(软件包: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。<匿名闭包>。<匿名闭包>。<匿名闭包> (软件包:mostadam / pages / boot_screen.dart:49:49)
I / flutter(24348):#9 _FutureBuilderState.build(软件包:flutter / src / widgets / async.dart)
I / flutter(24348):#10 StatefulElement.build(软件包: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& amp; ; SemanticsBinding& RendererBinding& WidgetsBinding.drawFrame(package:flutter / src / widgets / binding.dart:676:20)
I / flutter(24348):#15 _WidgetsFlutterBinding& BindingBase& GestureBinding& ServicesBinding& SchedulerBinding& Painting amp; SemanticsBinding& RendererBinding._handlePersistentFrameCallback(package:flutter / src / rendering / binding.dart:219:5)
I / flutter(24348):#16 _WidgetsFlutterBinding& BindingBase& GestureBinding& ServicesBinding& SchokelerBindingback._in :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(包: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 )
Anmol回答了评论中的问题。 / p>
解决方案n很简单,只需返回要导航的页面即可。但是对于某些罕见的特殊情况,IMO还远远不够。我希望我们能为以后的更新提供更好的选择。
解决方案:
而不是
Navigator.of(context).pushReplacement(MaterialPageRoute(builder:(context)=>
HomePage();
简单地说:
return HomePage();
相同于:
返回FirstScreen();
Edit: Problem solved exactly as I want in this new question topic:
Conditional Navigation inside Widget Tree
Old Question:
This is my Boot Screen and I want to create conditional Navigations but as I understand FutureBuilder does not have logic for Navigation.
This is my Boot Screen build method:
@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(),
),
);
},
);
},
),
);
}
As you see in the code, first I check up is user login before or not with an async method, then if he is login before, then I'm fetching the data related to him, once the fetching completed I want to navigate into the User Home page.
The error log:
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)
Anmol has answered the question on the comments.
The solution is easy, just return the page you want to navigate. But for some rare specific situations, it's not enough IMO. I hope we have better options for future updates.
Solution:
instead of
Navigator.of(context).pushReplacement( MaterialPageRoute( builder: (context) =>
HomePage();
simply put:
return HomePage();
same for:
return FirstScreen();
这篇关于嵌套未来中的导航的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!