更改浏览器时无法导航到初始路由错误 Url Flutter
Could not navigate to initial route error when changing browser Url Flutter
我正在更新我的代码以使用 Navigator 2.0 并使通过 NavigationBar
按钮的导航正常工作切换页面并相应地更新浏览器 Url 当我手动更改它时它抛出一个错误:
Could not navigate to initial route.
The requested route name was: "/retailers"
There was no corresponding route in the app, and therefore the initial route specified will be ignored and "/" will be used instead.
后退按钮也不起作用,并抛出 Duplicate GlobalKey detected in widget tree.
错误。
问题是我在解析器中检查了 routeInformation.location
吗?
编辑
我尝试将开关放在 uri.pathSegment.lenght
检查 uri.pathSegments.first
中,后退按钮现在可以正常工作了,但仍然抛出 Duplicate GlobalKey detected in widget tree.
错误。
if (uri.pathSegments.length > 0) {
print(
'Uri.segments.first is: ${uri.pathSegments.first}..uri.path is: ${uri.path}');
// switch (routeInformation.location) {
switch (uri.pathSegments.first) {
...
这是我的解析器:
class AppRouteInformationParser extends RouteInformationParser<RoutePath> {
@override
Future<RoutePath> parseRouteInformation(
RouteInformation routeInformation) async {
print(
'AppRouteInformationParser.parseRouteInformation called for ${routeInformation.location}');
final Uri uri = Uri.parse(routeInformation.location);
if (uri.pathSegments.length > 0) {
print(
'Uri.segments.first is: ${uri.pathSegments.first}, uri.path is: ${uri.path}');
} else {
print('AppRouteInformationParser uri has no segments and is $uri');
}
switch (routeInformation.location) {
// switch (uri.pathSegments.first) {
case '/':
print('AppRouteInformationParser.urlSegment switch case : /');
// return CyclistsPath();
return HomePath();
case CyclistsLandingRoute:
print(
'AppRouteInformationParser.routeInformation.location switch case: /cyclists');
return CyclistsPath();
case '/retailers':
print(
'AppRouteInformationParser.routeInformation.location switch case: /retailers');
return RetailersPath();
case '/map':
print(
'AppRouteInformationParser.routeInformation.location switch case: /map');
return MapPath();
case AboutRoute:
print(
'AppRouteInformationParser.routeInformation.location switch case: /about');
return AboutPath();
case TermsOfServiceRoute:
print(
'AppRouteInformationParser.routeInformation.location switch case: /terms-of-service');
return TermsOfServicePath();
case PrivacyPolicyRoute:
print(
'AppRouteInformationParser.routeInformation.location switch case: /privacy-policy');
return PrivacyPolicyPath();
case PrivacySettingsRoute:
print(
'AppRouteInformationParser.routeInformation.location switch case: /privacy-settings');
return PrivacySettingsPath();
case CommunityGuidelinesRoute:
print(
'AppRouteInformationParser.routeInformation.location switch case: /community-guidelines');
return CommunityGuidelinesPath();
case LegalNoticeRoute:
print(
'AppRouteInformationParser.routeInformation.location switch case: /legal-notice');
return LegalPath();
default:
print(
'### default AppRouteInformationParser.routeInformation.location switch case ## default: /');
return HomePath();
}
}
@override
RouteInformation restoreRouteInformation(RoutePath path) {
print(
'AppRouteInformationParser.restoreRouteInformation called for path ${path.selectedPath}');
switch (path.selectedPath) {
case '/':
// case CyclistsLandingRoute:
print('restoreRouteInformation RouteInformation.location: /');
return RouteInformation(location: '/');
case '/cyclists':
// case CyclistsLandingRoute:
print('restoreRouteInformation RouteInformation.location: /cyclists');
return RouteInformation(location: '/cyclists');
case '/retailers':
print('restoreRouteInformation RouteInformation.location: /retailers');
return RouteInformation(location: '/retailers');
case '/map':
print('restoreRouteInformation RouteInformation.location: /map');
return RouteInformation(location: '/map');
case '/about':
print('restoreRouteInformation RouteInformation.location: /about');
return RouteInformation(location: '/about');
case '/terms-of-service':
print(
'restoreRouteInformation RouteInformation.location: /terms-of-service');
return RouteInformation(location: '/terms-of-service');
case '/privacy-policy':
print(
'restoreRouteInformation RouteInformation.location: /privacy-policy');
return RouteInformation(location: '/privacy-policy');
case '/privacy-settings':
print(
'restoreRouteInformation RouteInformation.location: /privacy-settings');
return RouteInformation(location: '/privacy-settings');
case '/community-guidelines':
print(
'restoreRouteInformation RouteInformation.location: /community-guidelines');
return RouteInformation(location: '/community-guidelines');
case '/legal-notice':
print(
'restoreRouteInformation RouteInformation.location: /legal-notice');
return RouteInformation(location: '/legal-notice');
default:
print(
'restoreRouteInformation ### Default RouteInformation.location: /cyclists');
return RouteInformation(location: '/cyclists');
}
}
}
我还通过我设置的打印注意到,当应用程序首次加载时可能会有一个奇怪的循环:
解析器
AppRouteInformationParser.parseRouteInformation called for /
AppRouteInformationParser uri has no segments and is /
AppRouteInformationParser.urlSegment switch case : /
RuterDelegate
RouterDelegate.currentConfiguration appState.selectedPage is
解析器
AppRouteInformationParser.restoreRouteInformation called for path /
restoreRouteInformation RouteInformation.location: /
路由器代理
RouterDelegate.setNewRoutePath path is /
应用状态
AppState setting selectedPage to /
这会触发委托构建,所以再次
路由器代理
RouterDelegate.currentConfiguration appState.selectedPage is /
解析器
AppRouteInformationParser.restoreRouteInformation called for path /
restoreRouteInformation RouteInformation.location: /
非预期打印
路由器代理
RouterDelegate.currentConfiguration appState.selectedPage is /
解析器
AppRouteInformationParser.restoreRouteInformation called for path /
restoreRouteInformation RouteInformation.location: /
当按下按钮时,我只会得到:
按钮
1.selected tapped is /about
应用状态
AppState setting selectedPage to /about
路由器代理
RouterDelegate.currentConfiguration appState.selectedPage is /about
解析器
AppRouteInformationParser.restoreRouteInformation called for path /about
restoreRouteInformation RouteInformation.location: /about
折腾了几天终于找到问题所在:
在 main.dart 构建方法中,我返回一个 MaterialApp
,其中 MaterialApp.router
作为其 home:
而不是直接返回 MaterialApp.router
并移动所有MaterialApp
配置参数进去吧。
现在一切正常。
错误的方式:
AppRouterDelegate _routerDelegate = AppRouterDelegate();
AppRouteInformationParser _routeInformationParser =
AppRouteInformationParser();
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '',
color: Colors.red,
localizationsDelegates: [
const AppLocalizationsDelegate(),
GlobalMaterialLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: [
const Locale('en', 'US'),
const Locale('it', 'IT')
// const Locale('es', 'ES'),
],
localeResolutionCallback:
(Locale locale, Iterable<Locale> supportedLocales) {
for (Locale supportedLocale in supportedLocales) {
if (supportedLocale.languageCode == locale.languageCode ||
supportedLocale.countryCode == locale.countryCode) {
print('Web device Locale is $locale');
return supportedLocale;
}
}
return supportedLocales.first;
},
debugShowCheckedModeBanner: false,
home: MaterialApp.router(
routeInformationParser: _routeInformationParser,
routerDelegate: _routerDelegate),
);
}
正确的方法是:
AppRouterDelegate _routerDelegate = AppRouterDelegate();
AppRouteInformationParser _routeInformationParser =
AppRouteInformationParser();
@override
Widget build(BuildContext context) {
return MaterialApp.router(
routeInformationParser: _routeInformationParser,
routerDelegate: _routerDelegate,
debugShowCheckedModeBanner: false,
title: '',
color: Colors.red,
localizationsDelegates: [
const AppLocalizationsDelegate(),
GlobalMaterialLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: [
const Locale('en', 'US'),
const Locale('it', 'IT')
// const Locale('es', 'ES'),
],
localeResolutionCallback:
(Locale locale, Iterable<Locale> supportedLocales) {
for (Locale supportedLocale in supportedLocales) {
// if (UniversalPlatform.isWeb) {
if (supportedLocale.languageCode == locale.languageCode ||
supportedLocale.countryCode == locale.countryCode) {
print('Web device Locale is $locale');
return supportedLocale;
}
}
return supportedLocales.first;
},
// localeListResolutionCallback: ,
);
}
我正在更新我的代码以使用 Navigator 2.0 并使通过 NavigationBar
按钮的导航正常工作切换页面并相应地更新浏览器 Url 当我手动更改它时它抛出一个错误:
Could not navigate to initial route.
The requested route name was: "/retailers"
There was no corresponding route in the app, and therefore the initial route specified will be ignored and "/" will be used instead.
后退按钮也不起作用,并抛出 Duplicate GlobalKey detected in widget tree.
错误。
问题是我在解析器中检查了 routeInformation.location
吗?
编辑
我尝试将开关放在 uri.pathSegment.lenght
检查 uri.pathSegments.first
中,后退按钮现在可以正常工作了,但仍然抛出 Duplicate GlobalKey detected in widget tree.
错误。
if (uri.pathSegments.length > 0) {
print(
'Uri.segments.first is: ${uri.pathSegments.first}..uri.path is: ${uri.path}');
// switch (routeInformation.location) {
switch (uri.pathSegments.first) {
...
这是我的解析器:
class AppRouteInformationParser extends RouteInformationParser<RoutePath> {
@override
Future<RoutePath> parseRouteInformation(
RouteInformation routeInformation) async {
print(
'AppRouteInformationParser.parseRouteInformation called for ${routeInformation.location}');
final Uri uri = Uri.parse(routeInformation.location);
if (uri.pathSegments.length > 0) {
print(
'Uri.segments.first is: ${uri.pathSegments.first}, uri.path is: ${uri.path}');
} else {
print('AppRouteInformationParser uri has no segments and is $uri');
}
switch (routeInformation.location) {
// switch (uri.pathSegments.first) {
case '/':
print('AppRouteInformationParser.urlSegment switch case : /');
// return CyclistsPath();
return HomePath();
case CyclistsLandingRoute:
print(
'AppRouteInformationParser.routeInformation.location switch case: /cyclists');
return CyclistsPath();
case '/retailers':
print(
'AppRouteInformationParser.routeInformation.location switch case: /retailers');
return RetailersPath();
case '/map':
print(
'AppRouteInformationParser.routeInformation.location switch case: /map');
return MapPath();
case AboutRoute:
print(
'AppRouteInformationParser.routeInformation.location switch case: /about');
return AboutPath();
case TermsOfServiceRoute:
print(
'AppRouteInformationParser.routeInformation.location switch case: /terms-of-service');
return TermsOfServicePath();
case PrivacyPolicyRoute:
print(
'AppRouteInformationParser.routeInformation.location switch case: /privacy-policy');
return PrivacyPolicyPath();
case PrivacySettingsRoute:
print(
'AppRouteInformationParser.routeInformation.location switch case: /privacy-settings');
return PrivacySettingsPath();
case CommunityGuidelinesRoute:
print(
'AppRouteInformationParser.routeInformation.location switch case: /community-guidelines');
return CommunityGuidelinesPath();
case LegalNoticeRoute:
print(
'AppRouteInformationParser.routeInformation.location switch case: /legal-notice');
return LegalPath();
default:
print(
'### default AppRouteInformationParser.routeInformation.location switch case ## default: /');
return HomePath();
}
}
@override
RouteInformation restoreRouteInformation(RoutePath path) {
print(
'AppRouteInformationParser.restoreRouteInformation called for path ${path.selectedPath}');
switch (path.selectedPath) {
case '/':
// case CyclistsLandingRoute:
print('restoreRouteInformation RouteInformation.location: /');
return RouteInformation(location: '/');
case '/cyclists':
// case CyclistsLandingRoute:
print('restoreRouteInformation RouteInformation.location: /cyclists');
return RouteInformation(location: '/cyclists');
case '/retailers':
print('restoreRouteInformation RouteInformation.location: /retailers');
return RouteInformation(location: '/retailers');
case '/map':
print('restoreRouteInformation RouteInformation.location: /map');
return RouteInformation(location: '/map');
case '/about':
print('restoreRouteInformation RouteInformation.location: /about');
return RouteInformation(location: '/about');
case '/terms-of-service':
print(
'restoreRouteInformation RouteInformation.location: /terms-of-service');
return RouteInformation(location: '/terms-of-service');
case '/privacy-policy':
print(
'restoreRouteInformation RouteInformation.location: /privacy-policy');
return RouteInformation(location: '/privacy-policy');
case '/privacy-settings':
print(
'restoreRouteInformation RouteInformation.location: /privacy-settings');
return RouteInformation(location: '/privacy-settings');
case '/community-guidelines':
print(
'restoreRouteInformation RouteInformation.location: /community-guidelines');
return RouteInformation(location: '/community-guidelines');
case '/legal-notice':
print(
'restoreRouteInformation RouteInformation.location: /legal-notice');
return RouteInformation(location: '/legal-notice');
default:
print(
'restoreRouteInformation ### Default RouteInformation.location: /cyclists');
return RouteInformation(location: '/cyclists');
}
}
}
我还通过我设置的打印注意到,当应用程序首次加载时可能会有一个奇怪的循环:
解析器
AppRouteInformationParser.parseRouteInformation called for /
AppRouteInformationParser uri has no segments and is /
AppRouteInformationParser.urlSegment switch case : /
RuterDelegate
RouterDelegate.currentConfiguration appState.selectedPage is
解析器
AppRouteInformationParser.restoreRouteInformation called for path /
restoreRouteInformation RouteInformation.location: /
路由器代理
RouterDelegate.setNewRoutePath path is /
应用状态
AppState setting selectedPage to /
这会触发委托构建,所以再次
路由器代理
RouterDelegate.currentConfiguration appState.selectedPage is /
解析器
AppRouteInformationParser.restoreRouteInformation called for path /
restoreRouteInformation RouteInformation.location: /
非预期打印
路由器代理
RouterDelegate.currentConfiguration appState.selectedPage is /
解析器
AppRouteInformationParser.restoreRouteInformation called for path /
restoreRouteInformation RouteInformation.location: /
当按下按钮时,我只会得到:
按钮
1.selected tapped is /about
应用状态
AppState setting selectedPage to /about
路由器代理
RouterDelegate.currentConfiguration appState.selectedPage is /about
解析器
AppRouteInformationParser.restoreRouteInformation called for path /about
restoreRouteInformation RouteInformation.location: /about
折腾了几天终于找到问题所在:
在 main.dart 构建方法中,我返回一个 MaterialApp
,其中 MaterialApp.router
作为其 home:
而不是直接返回 MaterialApp.router
并移动所有MaterialApp
配置参数进去吧。
现在一切正常。
错误的方式:
AppRouterDelegate _routerDelegate = AppRouterDelegate();
AppRouteInformationParser _routeInformationParser =
AppRouteInformationParser();
@override
Widget build(BuildContext context) {
return MaterialApp(
title: '',
color: Colors.red,
localizationsDelegates: [
const AppLocalizationsDelegate(),
GlobalMaterialLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: [
const Locale('en', 'US'),
const Locale('it', 'IT')
// const Locale('es', 'ES'),
],
localeResolutionCallback:
(Locale locale, Iterable<Locale> supportedLocales) {
for (Locale supportedLocale in supportedLocales) {
if (supportedLocale.languageCode == locale.languageCode ||
supportedLocale.countryCode == locale.countryCode) {
print('Web device Locale is $locale');
return supportedLocale;
}
}
return supportedLocales.first;
},
debugShowCheckedModeBanner: false,
home: MaterialApp.router(
routeInformationParser: _routeInformationParser,
routerDelegate: _routerDelegate),
);
}
正确的方法是:
AppRouterDelegate _routerDelegate = AppRouterDelegate();
AppRouteInformationParser _routeInformationParser =
AppRouteInformationParser();
@override
Widget build(BuildContext context) {
return MaterialApp.router(
routeInformationParser: _routeInformationParser,
routerDelegate: _routerDelegate,
debugShowCheckedModeBanner: false,
title: '',
color: Colors.red,
localizationsDelegates: [
const AppLocalizationsDelegate(),
GlobalMaterialLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: [
const Locale('en', 'US'),
const Locale('it', 'IT')
// const Locale('es', 'ES'),
],
localeResolutionCallback:
(Locale locale, Iterable<Locale> supportedLocales) {
for (Locale supportedLocale in supportedLocales) {
// if (UniversalPlatform.isWeb) {
if (supportedLocale.languageCode == locale.languageCode ||
supportedLocale.countryCode == locale.countryCode) {
print('Web device Locale is $locale');
return supportedLocale;
}
}
return supportedLocales.first;
},
// localeListResolutionCallback: ,
);
}