嵌套未来中的导航 [英] Navigation inside Nested Future

查看:49
本文介绍了嵌套未来中的导航的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑:完全按照我想要的新问题主题解决问题:



小部件树中的条件导航



旧问题:



这是我的引导屏幕,我想创建条件导航,但是据我了解,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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆