我一直在问自己,我的应用程序应该坚持哪种导航风格: Navigator、命名路线、go_router 是我的选择。我的应用程序并不复杂,我不需要深层链接。但我需要从通知中打开一些屏幕。 现在我使用
Navigator.push/pop
。
我读过有关命名路由的内容,但我不喜欢传递参数的方式。与 Navigator 相比,它太复杂了,至少对我来说。
我使用 Navigator 的唯一问题是,在到达特定路线之前,我无法找到如何弹出某些路线。
这是我的用例:
用户进入屏幕 A 并遵循一些流程,直到屏幕 C。然后在屏幕 C 上,他们可以单击“完成”,并应重定向到屏幕 A。 如果他们想更正某些数据,他们当然可以使用后退按钮向后查看历史记录,C -> B -> A。
屏幕 A -> 屏幕 B -> 屏幕 C
现在我使用
Navigator.of(context).pop();
Navigator.of(context).pop();
,所以两次。
我已经尝试过 Navigator.of(context).popUntil((route) => route.isFirst);
,但它需要用户返回屏幕 A。屏幕 A 不是导航器上最底部的活动路线。
所以有几个选项,但为了保持代码干净和明确,我使用namedRoutes,您可以编写一些好的处理程序将争论作为地图而不是直接传递,但这意味着如果您选择使用导航器,您就有上下文手动处理的路线,例如:
navigatorKey.popUntil((route) => route.settings.name == TopNavigationScreen.id);
这将为您提供从堆栈中的位置返回到特定页面所需的信息。
我的典型设置是在每个“页面”上都有一个静态 ID,因此在设置中我可以将其称为每个路由的名称:
routes: {
StartScreen.id: (context) => const StartScreen()
}
稍后致电:
Navigator.pushNamed(StartScreen.id);
现在,如果您想要参数,请使用以下内容:
本质上是一样的,设置只需要知道如何获取“页面”的每个参数:
Map getSettingMap(context) => ModalRoute.of(context)!.settings.arguments as Map;
routes:{
ChatScreen.id: (context) => ChatScreen(
interactionId: getSettingMap(context)["interaction_id"],
userId: getSettingMap(context)["user_id"]
}
并用参数推动该路线
navigatorKey.pushNamed(ChatScreen.id, arguments: {
"interaction_id": interaction,
"user_id": currentUser.id,
});