草庐IT

dart - Flutter 中 OverlayEntry 引起的 Navigator.push() 断言

coder 2023-05-10 原文

我正在尝试在启动后立即处理我的应用程序的屏幕。

预期路线为:

boot -> check if is logged in -> if yes -> navigator.push() to MainWindow.
boot -> check if is logged in -> no snapshot data -> navigator.push() to LoadingScreen.
boot -> check if is logged in -> if no -> navigator.push() to LoginScreen.

一个函数在由 MaterialApp 主属性运行的启动时处理这种路由机制。

main.dart:

Widget build(BuildContext context) {
    return MaterialApp(
        title: "Preciso Metrologia",
        navigatorKey: navigatorKey,
        theme: ThemeData(
          brightness: Brightness.dark,
          primaryColor: Colors.lightBlue[400],
          accentColor: Colors.deepPurple[400],
        ),
        //home: LoginScreen()
        home: handleCurrentScreen());
  }

函数 handleCurrentScreen():

Widget handleCurrentScreen() {
    return new StreamBuilder<FirebaseUser>(
      stream: FirebaseAuth.instance.onAuthStateChanged,
      builder: (BuildContext context, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
          navigatorKey.currentState.push(MaterialPageRoute(builder: (context) => new PrecisoSplashScreen()));
        } else {
          if (snapshot.hasData) {
          navigatorKey.currentState.push(MaterialPageRoute(builder: (context) => new MainCertWindow(uuid: snapshot.data.uid)));
          }
          navigatorKey.currentState.push(MaterialPageRoute(builder: (context) => new PrecisoLoginScreen()));
        }
      }
    );
}

但它会返回一个与 Overlay Entry 相关的断言。

错误:

I/flutter ( 4502): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter ( 4502): The following assertion was thrown building StreamBuilder<FirebaseUser>(dirty, state:
I/flutter ( 4502): _StreamBuilderBaseState<FirebaseUser, AsyncSnapshot<FirebaseUser>>#db480):
I/flutter ( 4502): setState() or markNeedsBuild() called during build.
I/flutter ( 4502): This Overlay widget cannot be marked as needing to build because the framework is already in the
I/flutter ( 4502): process of building widgets. A widget can be marked as needing to be built during the build phase
I/flutter ( 4502): only if one of its ancestors is currently building. This exception is allowed because the framework
I/flutter ( 4502): builds parent widgets before children, which means a dirty descendant will always be built.
I/flutter ( 4502): Otherwise, the framework might not visit this widget during this build phase.
I/flutter ( 4502): The widget on which setState() or markNeedsBuild() was called was:
I/flutter ( 4502):   Overlay-[LabeledGlobalKey<OverlayState>#a2f7f](state: OverlayState#bbb92(entries:
I/flutter ( 4502):   [OverlayEntry#3da4e(opaque: false; maintainState: false), OverlayEntry#87966(opaque: false;
I/flutter ( 4502):   maintainState: true), OverlayEntry#d9c82(opaque: false; maintainState: false),
I/flutter ( 4502):   OverlayEntry#388a4(opaque: false; maintainState: true)]))
I/flutter ( 4502): The widget which was currently being built when the offending call was made was:
I/flutter ( 4502):   StreamBuilder<FirebaseUser>(dirty, state: _StreamBuilderBaseState<FirebaseUser,
I/flutter ( 4502):   AsyncSnapshot<FirebaseUser>>#db480).

最佳答案

您正在尝试为 home 属性提供一个 StreamBuilder,它实际上将提供导航器调用而不是 Widget 本身。你想要的是返回 PrecisoSplashScreen()PrecisoLoginScreen() 等等。

Widget handleCurrentScreen() {
    return new StreamBuilder<FirebaseUser>(
      stream: FirebaseAuth.instance.onAuthStateChanged,
      builder: (BuildContext context, snapshot) {
        if (snapshot.connectionState == ConnectionState.waiting) {
            return new PrecisoSplashScreen();
        } else {
          if (snapshot.hasData) {
            return new MainCertWindow(uuid: snapshot.data.uid);
          }
            return new PrecisoLoginScreen();
        }
      }
    );
}

此外,您可能需要考虑使用 FutureBuilder小部件。

关于dart - Flutter 中 OverlayEntry 引起的 Navigator.push() 断言,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53817422/

有关dart - Flutter 中 OverlayEntry 引起的 Navigator.push() 断言的更多相关文章

  1. ruby - 更改 $LOAD_PATH 时,为什么使用 unshift 而不是 push? - 2

    我发现ruby加载路径是一个数组,很多项目都是这样使用的:$:.unshift(File.expand_path("../../lib",__FILE__))可以将本地文件添加到ruby路径数组的前面,方便我们require或者load。所以,我希望知道为什么我们不使用push将文件添加到数组的末尾? 最佳答案 假设您有一个“date.rb”文件(为什么不呢)并且您想要加载这个文件,而不是标准库日期。如果您使用追加,当您调用require'date'时您的文件将永远不会被加载,因为它位于数组的末尾并且标准日期会在之前找到。因此,如果

  2. ruby-on-rails - 如何扩展 Ruby Test::Unit 断言以包含 assert_false? - 2

    显然在Test::Unit中没有assert_false。您将如何通过扩展断言并添加文件config/initializers/assertions_helper.rb来添加它?这是最好的方法吗?我不想修改test/unit/assertions.rb。顺便说一句,我不认为这是多余的。我使用的是assert_equalfalse,something_to_evaluate。这种方法的问题是很容易意外使用assertfalse,something_to_evaluate。这将始终失败,不会引发错误或警告,并且会在测试中引入错误。 最佳答案

  3. ruby-on-rails - RSpec 中单个设置的多个断言 - 2

    我想优化一些较慢的规范。此类规范的示例如下所示:require'rspec'classHeavyComputationdefcompute_resultsleep1#somethingcomputeheavyhere"verybigstring"endenddescribeHeavyComputation,'preferredstyle,butslow'dosubject{described_class.new.compute_result}it{shouldinclude'big'}it{shouldmatch'string'}it{shouldmatch/very/}#+50oth

  4. ruby - 你如何断言另一个 ruby​​ 模块的异常被抛出? (使用 assert_throws) - 2

    我正在尝试编写这样的代码:assert_throws(:ExtractionFailed){unit.extract_from('5x2005')}ExtractionFailed是Exception的一个简单子(monad)类,在test/unit下,我试图断言它在我调用unit.extract_from(...坏数据...)我已经将ExtractionFailed移动到SemanticText模块中,所以现在test/unit说:expectedtobethrownbutwasthrown.我尝试编写assert_throws(:SemanticText::ExtractionFa

  5. Flutter 环境变量配置和flutter doctor中的错误解决 - 2

    一、环境变量右键点击我的电脑-属性:然后找到环境变量 1.Android的SDK不在C盘的话需要额外配这个到用户环境变量:ANDROID_HOMED:\AndroidSDK2.然后在系统变量:Path中添加一条这样的值        D:\Flutter\flutter\bin             这个值写flutter包解压的实际地址即可 3.在系统变量中添加两个镜像变量:        变量名:FLUTTER_STORAGE_BASE_URL      变量值:https://storage.flutter-io.cn        变量名:PUB_HOSTED_URL      变量

  6. ruby - Minitest 断言在检查时失败 - 2

    每当我尝试assert_equal两个对象时,我总是会遇到这样的错误:NovisibledifferenceintheUser#inspectoutput.Youshouldlookattheimplementationof#==onUseroritsmembers.Time和Array也发生过这种情况。Minitest文档对此也没有说太多。我使用的是Ruby2.0.0,但我使用的是2.2.0,同样的事情发生了。也使用最新的minitest。此外,我正在运行Ubuntu14.10。 最佳答案 关于留言当断言失败时显示这条消息,有点不

  7. ruby-on-rails - 我如何断言 Rails 集成测试中没有路由匹配? - 2

    我有一个Rails3集成测试来测试我的路线。它包含如下测试:assert_routing("/#{@category.url.path}/#{@foo.url.path}",{:controller=>'foo',:action=>'show',:category=>@category.to_param,:foo=>@foo.to_param})我还想测试一个没有路由匹配的情况。显然,测试生成在这种情况下没有任何意义,所以我只需要assert_recognizes的倒数。我希望能够做这样的事情:assert_not_recognized('/adfhkljkdhasjklhjkldfa

  8. ruby - 在 Ruby 的正则表达式中,前瞻和后视概念如何支持这种零宽度断言概念? - 2

    我刚刚经历了这个概念Zero-WidthAssertions从文档中。我想到了一些快速的问题-为什么这样的名字Zero-WidthAssertions?Look-ahead怎么了和look-behind概念支持这样的Zero-WidthAssertions概念?什么这样的?,,=s,-4个符号在模式内指示?你能帮我集中精力了解实际发生的事情我还尝试了一些小代码来理解逻辑,但对它们的输出没有那么自信:irb(main):001:0>"foresight".sub(/(?!s)ight/,'ee')=>"foresee"irb(main):002:0>"foresight".sub(/(?

  9. ruby - 如何使用 mongoid/moped 进行 upsert/push - 2

    我正在使用Mongoid(v3)访问MongoDB,并希望执行此操作:db.sessionlogs.update({sessionid:'12345'},/*selectioncriteria*/{'$push':{rows:"newsetofdata"}},/*modification*/true/*upsert*/);这在mongoshell中工作正常。这也正是我想要的,因为它是一个单一的原子操作,这对我来说很重要,因为我会经常调用它。我不想做两个操作——一个获取然后一个更新。我已经通过mongoid尝试了很多东西,但无法让它工作。我怎样才能让MongoID不受影响,只将这个命令发

  10. git push报错:fatal: Authentication failed for ‘https://github.com/... - 2

    第一次用git传代码到GitHub时,填写用户名和密码出现报错:fatal:Authenticationfailedfor'https://github.com/试了下面的没用😢gitconfig-–globaluser.name"xxx"gitconfig--globaluser.email"xxx@xx.com"查看报错原因发现是因为git更新了认证方式在错误提示(糟糕忘截图)的网站里有说明-->https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-

随机推荐