Flutter 提供了一套完整的系統,用於在螢幕之間導航和處理深層連結。沒有複雜深層連結的小型應用程式可以使用 Navigator,而具有特定深層連結和導航要求的應用程式則應同時使用 Router,以正確處理 Android 和 iOS 上的深層連結,並在應用程式在 Web 上執行時與位址列保持同步。

要配置 Android 或 iOS 應用程式以處理深層連結,請參閱深層連結

使用 Navigator

#

Navigator 小部件以堆疊形式顯示螢幕,併為目標平臺使用正確的過渡動畫。要導航到新螢幕,請透過路由的 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 物件。MaterialPageRoute 物件是 Route 的子類,它指定了 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 都會將新的 Route 推送到 Navigator 上。

Flutter 也不支援使用命名路由的應用程式的瀏覽器前進按鈕。由於這些原因,我們不建議大多數應用程式使用命名路由。

使用 Router

#

具有高階導航和路由要求的 Flutter 應用程式(例如使用指向每個螢幕的直接連結的 Web 應用程式,或具有多個 Navigator 小部件的應用程式)應使用路由包,例如 go_router,它可以解析路由路徑並在應用程式收到新的深層連結時配置 Navigator

要使用 Router,請切換到 MaterialAppCupertinoApp 上的 router 建構函式,併為其提供 Router 配置。路由包,例如 go_router,通常提供路由配置,路由可以按如下方式使用:

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

由於 go_router 等包是宣告式的,因此當收到深層連結時,它們將始終顯示相同的螢幕。

同時使用 Router 和 Navigator

#

RouterNavigator 旨在協同工作。您可以透過宣告式路由包(例如 go_router)使用 Router API 進行導航,也可以透過在 Navigator 上呼叫命令式方法(例如 push()pop())進行導航。

當您使用 Router 或宣告式路由包進行導航時,Navigator 上的每個路由都是由頁面支援的,這意味著它是使用 Navigator 建構函式上的 pages 引數從 Page 建立的。相反,透過呼叫 Navigator.pushshowDialog 建立的任何 Route 都將向 Navigator 新增一個無頁面路由。如果您正在使用路由包,則由頁面支援的路由始終是可深層連結的,而無頁面路由則不是。

由頁面支援的 RouteNavigator 中刪除時,其後的所有無頁面路由也會被刪除。例如,如果深層連結透過從 Navigator 中刪除由頁面支援的路由進行導航,則其後的所有無頁面路由(直到下一個由頁面支援的路由)也會被刪除。

Web 支援

#

使用 Router 類的應用程式與瀏覽器歷史記錄 API 整合,以便在使用瀏覽器的後退和前進按鈕時提供一致的體驗。每當您使用 Router 進行導航時,都會向瀏覽器歷史記錄堆疊新增一個歷史記錄 API 條目。按下後退按鈕使用逆向時間導航,這意味著使用者將被帶到之前訪問過的、使用 Router 顯示的位置。這意味著,如果使用者從 Navigator 中彈出頁面,然後按下瀏覽器後退按鈕,則前一個頁面將被推回堆疊。

更多資訊

#

有關導航和路由的更多資訊,請檢視以下資源:

  • Flutter Cookbook 包含多個導航食譜,展示瞭如何使用 Navigator
  • NavigatorRouter API 文件包含有關如何在不使用路由包的情況下設定宣告式導航的詳細資訊。
  • 理解導航,是 Material Design 文件中的一頁,概述了設計應用程式導航的概念,包括對前進、向上和時間導航的解釋。
  • 學習 Flutter 的新導航和路由系統,Medium 上的一篇文章,描述瞭如何在不使用路由包的情況下直接使用 Router 小部件。
  • Router 設計文件包含 Router API 的動機和設計。