Flutter main.dart导航器上下文不包含导航器

时间:2020-11-07 01:17:16

标签: flutter

我看过其他几篇关于Navigator的相同错误的文章,或者它们的代码看起来不同,它在完全不同的地方失败,或者其他原因,我必须错过一些重要的事情。对我来说失败的地方仅仅是从后台或睡眠中恢复。应用程序生命周期检测到“恢复”,我想导航到登录页面以供用户选择配置文件或登录名。以下错误显示了我尝试在该函数didChangeAppLifecycleState(AppLifecycleState状态)中使用导航器的任何方式。实际上,如果我在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的方式不正确?

感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

didChangeAppLifecycleState方法与build方法不同,它不提供任何上下文。您必须通过设置导航的全局键来导航而不使用上下文:

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

将其传递给MaterialApp:

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

推路线:

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

Credits to this answer