Skip to main content

导航和路由

Flutter 提供了一个完整的系统,用于在屏幕之间导航和处理深度链接。没有复杂深度链接的小型应用程序可以使用Navigator,而具有特定深度链接和导航需求的应用程序也应该使用Router 来正确处理 Android 和 iOS 上的深度链接,并在应用程序在 Web 上运行时与地址栏保持同步。

要配置 Android 或 iOS 应用程序以处理深度链接,请参阅深度链接

使用 Navigator

#

Navigator 小部件使用目标平台的正确过渡动画将屏幕显示为堆栈。要导航到新屏幕,请通过路由的 BuildContext 访问 Navigator 并调用诸如 push()pop() 之类的命令式方法:

dart
child: const Text('打开第二个屏幕'),
onPressed: () {
  Navigator.of(context).push(
    MaterialPageRoute(builder: (context) => const SecondScreen()),
  );
},

因为 Navigator 保持 Route 对象(表示历史堆栈)的堆栈,所以 push() 方法也接受 Route 对象。MaterialPageRoute 对象是 Route 的子类,它指定了 Material Design 的过渡动画。有关如何使用 Navigator 的更多示例,请遵循 Flutter Cookbook 中的导航食谱 或访问Navigator API 文档

使用命名路由

#

具有简单导航和深度链接需求的应用程序可以使用 Navigator 进行导航,并使用MaterialApp.routes 参数进行深度链接:

dart
child: const Text('打开第二个屏幕'),
onPressed: () {
  Navigator.pushNamed(context, '/second');
},

/second 代表在 MaterialApp.routes 列表中声明的 命名路由 。有关完整示例,请遵循 Flutter Cookbook 中的使用命名路由导航 食谱。

限制

#

尽管命名路由可以处理深度链接,但行为始终相同且无法自定义。当平台接收到新的深度链接时,Flutter 会将新的 Route 推送到 Navigator 上,而不管用户当前位于何处。

对于使用命名路由的应用程序,Flutter 也不支持浏览器前进按钮。由于这些原因,我们不建议在大多数应用程序中使用命名路由。

使用 Router

#

具有高级导航和路由需求的 Flutter 应用程序(例如使用指向每个屏幕的直接链接的 Web 应用程序,或具有多个 Navigator 小部件的应用程序)应该使用诸如go_router之类的路由包,该包可以解析路由路径并在应用程序接收到新的深度链接时配置 Navigator

要使用 Router,请切换到 MaterialAppCupertinoApp 上的 router 构造函数,并为其提供 Router 配置。诸如go_router之类的路由包通常提供路由配置,路由可以使用如下方式:

dart
child: const Text('打开第二个屏幕'),
onPressed: () => context.go('/second'),

因为像 go_router 这样的包是 声明式 的,所以当接收到深度链接时,它们总是显示相同的屏幕。

结合使用 Router 和 Navigator

#

RouterNavigator 旨在协同工作。您可以通过声明式路由包(例如 go_router)或通过在 Navigator 上调用 push()pop() 等命令式方法来使用 Router API 进行导航。

当您使用 Router 或声明式路由包进行导航时,Navigator 上的每个路由都是 页面支持 的,这意味着它是使用 Navigator 构造函数上的pages 参数从Page 创建的。相反,通过调用 Navigator.pushshowDialog 创建的任何 Route 都将向 Navigator 添加 无页面 路由。如果您正在使用路由包,则 页面支持 的路由始终是可深度链接的,而 无页面 路由则不是。

当从 Navigator 中移除 页面支持Route 时,其后的所有 无页面 路由也会被移除。例如,如果深度链接通过从 Navigator 中移除 页面支持 的路由来进行导航,则其后的所有 无页面 路由(直到下一个 页面支持 的路由)也会被移除。

Web 支持

#

使用 Router 类 的应用程序与浏览器历史记录 API 集成,以便在使用浏览器的后退和前进按钮时提供一致的体验。每当您使用 Router 进行导航时,都会将历史记录 API 条目添加到浏览器的历史记录堆栈中。按下 后退 按钮使用_反向时间顺序导航_,这意味着用户将被带到先前使用 Router 显示的已访问位置。这意味着如果用户从 Navigator 中弹出页面,然后按下浏览器的 后退 按钮,则前一个页面将被推回到堆栈中。

更多信息

#

有关导航和路由的更多信息,请查看以下资源:

  • Flutter cookbook 包含多个导航食谱,这些食谱展示了如何使用 Navigator
  • NavigatorRouter API 文档包含有关如何在没有路由包的情况下设置声明式导航的详细信息。
  • 理解导航,Material Design 文档中的一个页面,概述了在应用程序中设计导航的概念,包括对前进、向上和时间顺序导航的解释。
  • 学习 Flutter 的新导航和路由系统,一篇关于 Medium 的文章,描述了如何在没有路由包的情况下直接使用 Router 小部件。
  • Router 设计文档 包含 Router API 的动机和设计。