导航和路由
Flutter 提供了一个完整的系统,用于在屏幕之间导航和处理深度链接。没有复杂深度链接的小型应用程序可以使用 Navigator
,而具有特定深度链接和导航要求的应用程序还应使用 Router
来正确处理 Android 和 iOS 上的深度链接,并在应用程序在 Web 上运行时与地址栏保持同步。
要配置你的 Android 或 iOS 应用程序以处理深度链接,请参阅 深度链接。
使用导航器
Navigator
小组件使用目标平台的正确过渡动画将屏幕显示为堆栈。要导航到新屏幕,请通过路由的 BuildContext
访问 Navigator
并调用命令式方法,例如 push()
or pop()
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => const SongScreen(song: song),
),
);
},
child: Text(song.name),
由于 Navigator
保留 Route
对象(表示历史记录堆栈)的堆栈,因此 push()
方法也采用 Route
对象。 MaterialPageRoute
对象是 Route
的子类,它指定 Material Design 的过渡动画。有关如何使用 Navigator
的更多示例,请按照 Flutter Cookbook 中的 导航食谱 或访问 Navigator API 文档。
使用命名路由
具有简单导航和深度链接要求的应用程序可以使用 Navigator
进行导航,并使用 MaterialApp.routes
参数进行深度链接
@override
Widget build(BuildContext context) {
return MaterialApp(
routes: {
'/': (context) => HomeScreen(),
'/details': (context) => DetailScreen(),
},
);
}
此处指定的路由称为命名路由。有关完整示例,请按照 Flutter Cookbook 中的使用命名路由进行导航配方操作。
限制
虽然命名路由可以处理深度链接,但行为始终相同,且无法自定义。当平台收到新的深度链接时,Flutter 会将新的Route
推送到 Navigator,而不管用户当前位于何处。
对于使用命名路由的应用程序,Flutter 也不支持浏览器前进按钮。由于这些原因,我们不建议在大多数应用程序中使用命名路由。
使用路由器
具有高级导航和路由要求的 Flutter 应用程序(例如使用直接链接到每个屏幕的 Web 应用程序,或具有多个Navigator
小部件的应用程序)应使用路由包,例如go_router,它可以解析路由路径并在应用程序收到新的深度链接时配置Navigator
。
要使用路由器,请切换到MaterialApp
或CupertinoApp
上的router
构造函数,并为其提供Router
配置。路由包(例如go_router)通常会为您提供配置。例如
MaterialApp.router(
routerConfig: GoRouter(
// …
)
);
由于 go_router 等包是声明性的,因此在收到深度链接时,它们将始终显示相同的屏幕。
同时使用路由器和导航器
Router
和Navigator
旨在协同工作。您可以通过声明性路由包(例如go_router
)使用Router
API 导航,或通过在Navigator
上调用命令式方法(例如push()
和pop()
)进行导航。
使用 Router
或声明式路由包进行导航时,导航器上的每个路由都是页面支持的,这意味着它是由 Page
使用 Navigator
构造函数上的 pages
参数创建的。相反,通过调用 Navigator.push
或 showDialog
创建的任何 Route
都将向导航器添加一个无页面路由。如果你正在使用路由包,页面支持的路由始终是深层链接的,而无页面路由则不是。
当从 Navigator
中移除页面支持的 Route
时,其后的所有无页面路由也将被移除。例如,如果深层链接通过从导航器中移除页面支持的路由来进行导航,则所有无页面 _路由(直到下一个页面支持的路由)也将被移除。
Web 支持
使用 Router
类的应用与浏览器历史记录 API 集成,以便在使用浏览器的后退和前进按钮时提供一致的体验。每当你使用 Router
进行导航时,历史记录 API 项都会被添加到浏览器的历史记录堆栈中。按后退按钮使用反向时间顺序导航,这意味着用户将被带到之前使用 Router
显示的访问位置。这意味着,如果用户从 Navigator
中弹出页面,然后按浏览器的后退按钮,则前一页将被推回堆栈中。
更多信息
有关导航和路由的更多信息,请查看以下资源
- Flutter 食谱包含多个 导航食谱,展示如何使用
Navigator
。 Navigator
和Router
API 文档包含有关如何在没有路由包的情况下设置声明式导航的详细信息。- 理解导航,Material Design 文档中的一页,概述了在你的应用中设计导航的概念,包括对前向、向上和按时间顺序导航的解释。
-
了解 Flutter 的新导航和路由系统,Medium 上的一篇文章,描述了如何在没有路由包的情况下直接使用
Router
小组件。 - Router 设计文档 包含 Router API 的动机和设计。