简体   繁体   English

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

[英]Assertion on Navigator.push() caused by OverlayEntry in Flutter

I'm trying to handle my app's screens moments after boot. 我试图在启动后立即处理我的应用程序的屏幕。

Expected Routes would be: 预期路线将是:

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.

A Function handles this routing mechanism on boot being ran by MaterialApp home property. Function在由MaterialApp home属性运行的引导时处理此路由机制。

main.dart: 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());
  }

Function 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()));
        }
      }
    );
}

But instead it returns a Assertion related to Overlay Entry. 但它会返回与叠加条目相关的断言。

Error: 错误:

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).

You're trying to give the home property a StreamBuilder that will actually provide navigator calls instead of a Widget itself. 你试图给home属性一个StreamBuilder ,它实际上会提供导航器调用而不是Widget本身。 What you want is return a PrecisoSplashScreen() or PrecisoLoginScreen() and so on. 你想要的是返回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();
        }
      }
    );
}

Also, you may want to consider using a FutureBuilder widget. 此外,您可能需要考虑使用FutureBuilder小部件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM