我看過其他幾篇關于Navigator同樣錯誤的文章,要么他們的代碼看起來不一樣,要么在完全不同的地方失敗,要么是其他原因,我一定遺漏了一些重要的東西。對我來說,這失敗的地方只是從后臺或睡眠中恢復。應用程序生命周期檢測到“恢復”,我想導航到登錄頁面,以便用戶選擇配置文件或登錄。下面的錯誤顯示了我嘗試在函數didChangeAppLifecycleState(AppLifecycleState)中使用導航器的任何方式。實際上,如果我在main.dart中的任何地方使用Navigator,它會給出錯誤。在main.dartNavigator之外工作很好。
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);
}
}
我也嘗試跳過我的導航服務,直接使用Navigator,但是同樣的錯誤顯示出來了。
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => LoginPage(),
),
);
正如其他帖子所建議的那樣,我嘗試使用GlobalKey,但是使用RouteObserver的NavService()在我這樣做時會中斷。
導航服務和頁面路由在應用程序中的任何地方都能很好地工作。只有在main.dart中導航時,我才有這個問題。我只是注意到如果我把上面的Navigator.of().push放在initState()中,就會得到相同的錯誤。也許我的材料應用程序設置錯誤?還是我沒有正確使用導航服務?
謝謝你的幫助!
didChangeAppLifecycleState
方法不像build方法提供任何上下文。您必須在不使用上下文的情況下導航,方法是為導航設置全局鍵:傳遞給材料應用程序:
Push routes:
這個答案的功勞