我看过其他几篇关于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的方式不正确?
感谢您的帮助!
答案 0 :(得分:1)
didChangeAppLifecycleState
方法与build方法不同,它不提供任何上下文。您必须通过设置导航的全局键来导航而不使用上下文:
final GlobalKey<NavigatorState> navigatorKey = GlobalKey<NavigatorState>();
将其传递给MaterialApp:
MaterialApp(
title: 'MyApp',
onGenerateRoute: generateRoute,
navigatorKey: navigatorKey,
);
推路线:
navigatorKey.currentState.pushNamed('/someRoute');