跳转至正文

路由和导航

Flutter路由和导航的概览。

Flutter 提供了一套完整的系统在界面之间导航并处理深层链接。没有复杂深层链接的小型应用可以使用 Navigator,而有特定深层链接与导航需求的应用还应使用 Router,以便在 Android 和 iOS 上正确处理深层链接,并在 Web 上运行时与地址栏保持同步。

要为 Android 或 iOS 应用配置深层链接处理,请参阅深层链接

使用 Navigator

#

Navigator widget 以栈的形式显示界面,并使用目标平台对应的过渡动画。要导航到新界面,通过路由的 BuildContext 访问 Navigator,并调用 push()pop() 等命令式方法:

dart
child: const Text('Open second screen'),
onPressed: () {
  Navigator.of(context).push(
    MaterialPageRoute<void>(
      builder: (context) => const SecondScreen(),
    ),
  );
},

由于 Navigator 维护 Route 对象栈(表示历史栈),push() 方法也需要传入 Route 对象。 MaterialPageRouteRoute 的子类,用于指定 Material Design 的过渡动画。更多 Navigator 用法示例,请参阅 Flutter Cookbook 中的 导航示例,或访问 Navigator API 文档

使用命名路由

#

导航与深层链接需求较简单的应用,可用 Navigator 进行导航,并用 MaterialApp.routes 参数处理深层链接:

dart
child: const Text('Open second screen'),
onPressed: () {
  Navigator.pushNamed(context, '/second');
},

/second 表示在 MaterialApp.routes 列表中声明的 命名路由。完整示例请参阅 Flutter Cookbook 中的 使用命名路由导航

局限性

#

尽管命名路由可以处理深层链接,但行为始终相同且无法自定义。当平台收到新的深层链接时,无论用户当前在何处, Flutter 都会在 Navigator 上压入新的 Route

使用命名路由的应用也不支持浏览器的前进按钮。因此,我们不建议大多数应用使用命名路由。请改用 go_router 等路由 package,或将 NavigatorMaterialPageRoute 配合使用。

使用 Router

#

具有高级导航与路由需求(例如 Web 应用为每个界面提供直接链接,或应用包含多个 Navigator widget)的 Flutter 应用,应使用 go_router 等路由 package,以便解析路由路径,并在收到新深层链接时配置 Navigator

要使用 Router,请在 MaterialAppCupertinoApp 上改用 router 构造函数,并提供 Router 配置。go_router 等路由 package 通常提供路由配置,可按如下方式使用路由:

dart
child: const Text('Open second screen'),
onPressed: () => context.go('/second'),

由于 go_router 等 package 是 声明式 的,收到深层链接时始终会显示相同的界面。

同时使用 Router 与 Navigator

#

RouterNavigator 设计为协同工作。你可以通过声明式路由 package(如 go_router)使用 Router API 导航,也可以在 Navigator 上调用 push()pop() 等命令式方法。

使用 Router 或声明式路由 package 导航时, Navigator 上的每条路由都是 由 Page 支持 (page-backed) 的,即通过 Navigator 构造函数的 pages 参数由 Page 创建。反之,通过 Navigator.pushshowDialog 创建的 Route 会向 Navigator 添加 无 Page (pageless) 路由。若使用路由 package,由 Page 支持 的路由始终可深层链接,而 无 Page 的路由则不行。

当从 Navigator 移除 由 Page 支持Route 时,其后的所有 无 Page 路由也会一并移除。例如,若深层链接通过从 Navigator 移除 由 Page 支持 的路由进行导航,其后(直到下一条 由 Page 支持 的路由之前)的所有 无 Page 路由也会被移除。

Web 支持

#

使用 Router 类的应用会与浏览器 History API 集成,在使用浏览器后退与前进按钮时提供一致的体验。每当你通过 Router 导航,都会在浏览器历史栈中添加一条 History API 记录。按下 后退 按钮会使用 逆时间顺序导航,即用户会回到先前通过 Router 显示的访问位置。这意味着若用户从 Navigator 弹出页面后再按浏览器 后退 按钮,先前的页面会重新压入栈中。

更多信息

#

有关导航与路由的更多信息,请参阅以下资源:

  • Flutter Cookbook 包含多个 导航示例,展示如何使用 Navigator

  • NavigatorRouter API 文档说明如何在不使用路由 package 的情况下设置声明式导航。

  • 理解导航(Material Design 文档)概述应用导航的设计概念,包括前向、向上与时间顺序导航的说明。

  • 学习 Flutter 的新导航与路由系统(Medium 文章)介绍如何在不使用路由 package 的情况下直接使用 Router widget。

  • Router 设计文档 包含 Router API 的动机与设计。