【问题标题】:Flutter main.dart Navigator context does not include a NavigatorFlutter main.dart Navigator 上下文不包含 Navigator
【发布时间】:2021-02-19 17:07:01
【问题描述】:

我查看了其他几篇关于导航器的相同错误的帖子,它们的代码看起来不同,它在完全不同的地方失败,或者其他原因,我一定错过了一些重要的东西。这对我来说失败的地方只是从后台或睡眠中恢复。应用程序生命周期检测到“恢复”,我想导航到登录页面以供用户选择个人资料或登录名。下面的错误显示了我尝试在该函数 didChangeAppLifecycleState(AppLifecycleState state) 中使用导航器的任何方式。实际上,如果我在 main.dart 中的任何地方使用 Navigator,它会给出错误。在 main.dart Navigator 之外工作得很好。

Navigator operation requested with a context that does not include a Navigator.
The context used to push or pop routes from the Navigator must be that of a widget that is a descendant of a Navigator widget.

main.dart 中导致错误的代码:

@override
void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);
    print("State changed! ${state}");
    setState(() {
        _notification = state;
    });
    if(state == AppLifecycleState.resumed){
        NavService().navigateTo(context, '/login');
    }
}

main.dart 构建如下所示:

@override
Widget build(BuildContext context) {
    return 
    MaterialApp(
    theme: new ThemeData(
        primarySwatch: themeSwatchColor,
        brightness: Brightness.light,
        primaryColor: themePrimaryColor,
        accentColor: themeAccentColor,
    ),
    initialRoute: '/',
    navigatorObservers: <NavigatorObserver>[
        NavService(), // this will listen all changes
        
    ],
    onGenerateRoute: (routeSettings) {
        switch (routeSettings.name) {
            case '/':
                return MaterialPageRoute(builder: (_) => LoginPage());
            case '/login':
                return MaterialPageRoute(builder: (_) => LoginPage());
            case '/home':
                return MaterialPageRoute(builder: (_) => HomePage());
            case '/items':
                return MaterialPageRoute(builder: (_) => ItemLookupPage());
            case '/settings':
                return MaterialPageRoute(builder: (_) => SettingsPage());
            case '/oldsettings':
                return MaterialPageRoute(builder: (_) => SecondPage());
            case '/pickorders':
                return MaterialPageRoute(builder: (_) => ReceivedOrdersPage());
            case '/orders':
                return MaterialPageRoute(builder: (_) => OrdersPage());
            case '/receiving':
                return MaterialPageRoute(builder: (_) => ReceivingPage());
            case '/inventory':
                return MaterialPageRoute(builder: (_) => InventoryPage());
            default:
                return MaterialPageRoute(builder: (_) => LoginPage());
        }
    },

    home: (noAccount == true)
        ? LoginPage()
        : HomePage(),
    );
}

NavService.dart:

class NavService extends RouteObserver {

    void saveLastRoute(String lastRoute) async {
        if(lastRoute != "/login" && lastRoute != "/error"){
            final SharedPreferences prefs = await SharedPreferences.getInstance();
            prefs.setString('last_route', lastRoute);
        }
    }

    Future<dynamic> navigateTo(BuildContext context, String routeName, {Map data}) async {
        saveLastRoute(routeName);
        return Navigator.pushNamed(context, routeName,  arguments: data);
    }
}

我也尝试跳过我的 NavService 并直接使用 Navigator,但显示相同的错误。

Navigator.of(context).push(
    MaterialPageRoute(
        builder: (context) => LoginPage(),
    ),
);

我尝试按照其他帖子的建议使用 GlobalKey,但使用 RouteObserver 的 NavService() 在我这样做时会中断。

NavService 和页面路由在应用程序的任何地方都能很好地工作。只有在 main.dart 中导航时我才遇到问题。我只是注意到如果我将上面的 Navigator.of().push 放在 initState() 中,我会得到同样的错误。也许我的 MaterialApp 设置错误?还是我错误地使用了 NavService?

感谢您的帮助!

【问题讨论】:

    标签: flutter


    【解决方案1】:

    与 build 方法不同,didChangeAppLifecycleState 方法不提供任何上下文。通过为导航设置全局键,您必须在不使用上下文的情况下进行导航:

    final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
    

    将其传递给 MaterialApp:

        MaterialApp(
          title: 'MyApp',
          onGenerateRoute: generateRoute,
          navigatorKey: navigatorKey,
        );
    

    推送路线:

    navigatorKey.currentState.pushNamed('/someRoute');
    

    Credits to this answer

    【讨论】:

    • 非常感谢!我想当我尝试使用 navigatorKey 时,我将它放在 NavService() 中。我只是将它添加到 main.dart 中的 MyAPP() 中,并且效果很好。 NavService() 在其他任何地方都可以正常工作。啊。有时它只是你没有捕捉到的一点点差异,你需要第二双眼睛来指出新的东西。再次感谢!
    猜你喜欢
    • 2021-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-15
    • 2020-05-05
    • 2021-08-02
    • 2021-05-23
    相关资源
    最近更新 更多