如何安全地导航到我的颤振应用程序的默认路由(“主页”)?
Posted
技术标签:
【中文标题】如何安全地导航到我的颤振应用程序的默认路由(“主页”)?【英文标题】:How can I safely navigate to the default route ("home page") of my flutter app? 【发布时间】:2021-02-10 05:13:55 【问题描述】:编辑:最初这篇文章是专门针对使用全局导航器的,但我发现这个案例并不是专门针对使用全局导航器的。相反,它是一个错误,可能因滥用 Navigator API 而发生。
Flutter 1.22.0 • channel beta • https://github.com/flutter/flutter.git
Framework • revision d408d302e2 (4 weeks ago) • 2020-09-29 11:49:17 -0700
Engine • revision 5babba6c4d
Tools • Dart 2.10.0
我遵循了之前 SO 帖子中的建议。这在某种程度上有效: How to navigate without context in flutter app?
但是,我在简单地使用全局导航键时遇到了一些问题。我无法使用路由谓词调用 popUntil 以导航回我的主屏幕,并且因为 I cannot view the Navigator history stack,我无法有效地调试它。
/// constants/keys.dart
final GlobalKey<NavigatorState> navKey = new GlobalKey<NavigatorState>();
/// constants/routes.dart
const String HOME = 'home';
const String SCREEN_A = 'a';
const String SCREEN_B = 'b';
/// main.dart
class App extends StatelessWidget
@override
Widget build(BuildContext context)
return MaterialApp(
home: Home(),
navigatorKey: Keys.navKey,
onGenerateRoute: (routeSettings)
switch (routeSettings.name)
case Routes.HOME:
return MaterialPageRoute(
builder: (context) => Home(),
settings: RouteSettings(name: Routes.HOME),
);
case Routes.SCREEN_A:
return MaterialPageRoute(
builder: (context) => ScreenA(),
settings: RouteSettings(name: Routes.SCREEN_A),
);
case Routes.SCREEN_B:
return MaterialPageRoute(
builder: (context) => ScreenB(),
settings: RouteSettings(name: Routes.SCREEN_B),
);
default:
return MaterialPageRoute(
builder: (context) => Home(),
settings: RouteSettings(name: Routes.HOME),
);
,
);
这表明您不能使用页面查看使用 Navigator API 添加的历史记录。
/// Experiment, instrument build of Home, ScreenA, ScreenB with code to view pages:
Navigator nav = Keys.navKey.currentWidget;
print("Location: Home, Number of pages: $nav.pages.length");
for (Page page in nav.pages)
print("Page: $page.name, $page.key, $page.toString()");
/// OUTPUT:
// Home, Number of pages: 0
// ScreenA, Number of pages: 0
// ScreenB, Number of pages: 0
I did not expect pages to display the navigation history
一些Routes不对应Page对象,即那些 使用 Navigator API(推送和好友)添加到历史记录。一种 不对应 Page 对象的路由称为无页 route 并绑定到与 Page 对象相对应的 Route 历史上低于它。
结束切线
我在使用 Navigator 时遇到的主要痛点是我需要从没有构建上下文的方法中进行导航,并且需要全局键来访问诸如 Navigator 之类的小部件。例如,我必须为蓝牙连接失败附加一个监听器,然后从监听器导航回主屏幕。为此,我不得不依赖全局导航键。我也更喜欢访问全局导航键而不是调用 Navigator.of(context)。
但是,由于我无法查看 Navigator 历史堆栈,因此无法轻松调试我的问题。
我可以通过全局导航键使用这些调用向前导航:
Keys.navKey.currentState.pushNamed(Routes.HOME);
我可以使用任何一个:
Keys.navKey.currentState.pushNamedAndRemoveUntil(Routes.HOME, (Route<dynamic> route) => false);
或:
Keys.navKey.currentState.pushReplacementNamed(Routes.HOME);
向后导航。
但我不能简单地弹出内部导航器历史堆栈而不出现黑屏。
/// Black Screen
Keys.navKey.currentState.popUntil(ModalRoute.withName(Routes.HOME));
对我来说,正确的方法似乎是 popUntil,因为它会从堆栈中弹出除所需路由之外的所有内容。为什么在这个例子中不能简单地调用 popUntil 来安全地导航回主屏幕?
【问题讨论】:
【参考方案1】:我可以使用这个 sn-p 导航回默认路由:
Keys.navKey.currentState.popUntil(ModalRoute.withName(Navigator.defaultRouteName));
使用调试器,我看到默认路由名称是 '/' 而不是 'home'。使用 navigator 以编程方式导航不会将初始路由作为 home 推送到堆栈上。这是有道理的。我从不调用 Keys.navKey.currentState.push('home')。如果您想使用导航器返回应用程序默认屏幕,请记住这一点,上述方法调用似乎是正确的方法,除非您找到一种方法将导航器堆栈的底部设置为您的回家路线。
【讨论】:
以上是关于如何安全地导航到我的颤振应用程序的默认路由(“主页”)?的主要内容,如果未能解决你的问题,请参考以下文章
如何通过使用 Vue.js 中的路由器概念单击按钮来简单地从一个组件(主页)导航到另一个组件