【问题标题】:Navigator pushReplacement error in flutter导航器推送替换错误
【发布时间】:2021-10-30 12:44:04
【问题描述】:

导航到下一页后,我的启动画面出现问题

class SplashScreen extends StatelessWidget {
  final backgroundColor = 0xffF6F6F6;

  @override
  Widget build(BuildContext context) {
    Future.delayed(const Duration(seconds: 3), () {
      Navigator.of(context).pushReplacement(
        MaterialPageRoute(
          builder: (context) => Wrapper(),
        ),
      );
    });

    return ScreenUtilInit(
      builder: () => MaterialApp(...),
    );
  }
}

简单的 'Navigator.of(context).push' 工作正常,没有任何显示 但是使用 pushReplacement 下一个错误显示:

D/NetworkSecurityConfig( 8102): No Network Security Config specified, using platform default
W/System  ( 8102): Ignoring header X-Firebase-Locale because its value was null.
W/DynamiteModule( 8102): Local module descriptor class for providerinstaller not found.
I/DynamiteModule( 8102): Considering local module providerinstaller:0 and remote module providerinstaller:0
W/ProviderInstaller( 8102): Failed to load providerinstaller module: No acceptable module found. Local version is 0 and remote version is 0.
I/com.my_app( 8102): The ClassLoaderContext is a special shared library.
I/chatty  ( 8102): uid=10088(com.my_app) AsyncTask #2 identical 1 line
I/com.my_app( 8102): The ClassLoaderContext is a special shared library.
V/NativeCrypto( 8102): Registering com/google/android/gms/org/conscrypt/NativeCrypto's 294 native methods...
W/com.my_app( 8102): Accessing hidden method Ljava/security/spec/ECParameterSpec;->getCurveName()Ljava/lang/String; (light greylist, reflection)
I/ProviderInstaller( 8102): Installed default security provider GmsCore_OpenSSL
W/com.my_app( 8102): Accessing hidden method Ljava/security/spec/ECParameterSpec;->setCurveName(Ljava/lang/String;)V (light greylist, reflection)
D/FirebaseAuth( 8102): Notifying id token listeners about user ( sXisKRx15aeLiT7rGR8XS4yGGNJ2 ).
E/flutter ( 8102): [ERROR:flutter/shell/common/shell.cc(93)] Dart Unhandled Exception: Looking up a deactivated widget's ancestor is unsafe.
E/flutter ( 8102): At this point the state of the widget's element tree is no longer stable.
E/flutter ( 8102): To safely refer to a widget's ancestor in its dispose() method, save a reference to the ancestor by calling dependOnInheritedWidgetOfExactType() in the widget's didChangeDependencies() method., stack trace: #0      Element._debugCheckStateIsActiveForAncestorLookup.<anonymous closure> (package:flutter/src/widgets/framework.dart:4032:9)
E/flutter ( 8102): #1      Element._debugCheckStateIsActiveForAncestorLookup (package:flutter/src/widgets/framework.dart:4046:6)
E/flutter ( 8102): #2      Element.findAncestorStateOfType (package:flutter/src/widgets/framework.dart:4093:12)
E/flutter ( 8102): #3      Navigator.of (package:flutter/src/widgets/navigator.dart:2736:40)
E/flutter ( 8102): #4      SplashScreen.build.<anonymous closure> (package:first_project_test/screens/home/splash.dart:13:17)
E/flutter ( 8102): #5      new Future.delayed.<anonymous closure> (dart:async/future.dart:315:39)
E/flutter ( 8102): #6      Timer._createTimer.<anonymous closure> (dart:async-patch/timer_patch.dart:18:15)
E/flutter ( 8102): #7      _Timer._runTimers (dart:isolate-patch/timer_impl.dart:395:19)
E/flutter ( 8102): #8      _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:426:5)
E/flutter ( 8102): #9      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12)

它仅在我使用“Run 'main.dart'”重新渲染页面时显示 我用 ScreenUtilInit 包装了 Material 应用程序,因为

我还在我的主文件中使用 InitializerWidget 类运行 SplashScreen,如果您需要有关它的更多信息,请告诉我❤

【问题讨论】:

    标签: firebase flutter dart navigator


    【解决方案1】:

    我们不应该直接调用build方法中的函数。
    只要在创建 Widget 的 State 时只需要实现一次逻辑,就使用 initState

    1. Stateless 更改为Stateful
    class SplashScreen extends StatefulWidget {
     const SplashScreen({Key? key}) : super(key: key);
    
     @override
     _SplashScreenState createState() => _SplashScreenState();
    }
    
    class _SplashScreenState extends State<SplashScreen> {
     
     @override
     Widget build(BuildContext context) {
       return SomeWidget();
     }
    
    }
    
    1. 现在将所需的逻辑放入initState 方法中。
    class _SplashScreenState extends State<SplashScreen> {
      
      @override
      initState() {
        super.initState();
    
        Future.delayed(const Duration(seconds: 3), () {
          Navigator.of(context).pushReplacement(
            MaterialPageRoute(
              builder: (context) => Wrapper(),
            ),
          );
        });
      }
    
    // other methods 
    
    }
    

    【讨论】:

    • 主要问题只是在构建器或无状态小部件内部调用方法?
    • build 方法。 build 方法可以被多次调用,因此future.delayed 也将被多次调用。虽然主要原因是函数应该在回调(如按钮的onPressed)和小部件循环方法(如initState)中调用。参考thisthis
    猜你喜欢
    • 1970-01-01
    • 2013-03-09
    • 2020-10-30
    • 2018-05-05
    • 2021-06-17
    • 2013-07-19
    • 1970-01-01
    • 2014-01-11
    • 2020-12-01
    相关资源
    最近更新 更多