Skip to main content

Route 和 Navigator 重構

Route 和 Navigator 類別的部分 API 及函式簽章已經變更。

摘要

#

Route 類別不再於 overlay 中管理其 overlay entries,且其 install() 方法不再具有 insertionPoint 參數。 RouteSetting 中的 isInitialRoute 屬性已被棄用,Navigator.pop() 也不再回傳任何值。

背景

#

我們重構了 navigator API,以因應新的 page API 以及 Router 設計文件中所提到的 Router 元件 (Widget) 的導入。 這次重構帶來了一些函式簽章的變更,目的是讓現有的 navigator API 能夠繼續與新的 page API 搭配運作。

變更說明

#

Navigator.pop() 的布林值回傳結果定義不明確,且使用者可透過呼叫 Navigator.canPop() 達到相同效果。 由於 Navigator.canPop() 的 API 定義較為明確,因此我們簡化了 Navigator.pop(),使其不再回傳布林值。

另一方面,navigator 需要能夠手動調整 overlay 中的 entries,以便使用者在新 API 下變更路由歷史紀錄。 我們調整為 route 僅負責建立與銷毀其 overlay entries,而 navigator 則負責將 overlay entries 插入或移除 overlay。 同時,我們也移除了 Route.install()insertionPoint 參數,因為在這次變更後已經不再需要。

最後,作為重構的一部分,我們從 RouteSetting 移除了 isInitialRoute 屬性,並提供了 onGenerateInitialRoutes API 以便完全掌控初始路由的產生。

遷移指南

#

情境 1:應用程式依賴 pop() 回傳布林值。

dart
TextField(
  onTap: () {
    if (Navigator.pop(context))
      print('There still is at least one route after pop');
    else
      print('Oops! No more routes.');
  }
)

你可以將 Navigator.canPop()Navigator.pop() 結合使用,以達到相同的效果。

dart
TextField(
  onTap: () {
    if (Navigator.canPop(context))
      print('There still is at least one route after pop');
    else
      print('Oops! No more routes.');
    // Our navigator pops the route anyway.
    Navigator.pop(context);
  }
)

情境 2:應用程式根據 isInitialRoute 產生路由。

dart
MaterialApp(
  onGenerateRoute: (RouteSetting setting) {
    if (setting.isInitialRoute)
      return FakeSplashRoute();
    else
      return RealRoute(setting);
  }
)

有多種方式可以遷移這項變更。 其中一種方式是為 MaterialApp.initialRoute 設定明確的值。 接著,你可以在需要 isInitialRoute 的地方,改為檢查這個值。 由於 initialRoute 的預設值是在 Flutter 的範疇之外繼承的, 因此你必須為它設定明確的值。

dart
MaterialApp(
  initialRoute: '/', // Set this value explicitly. Default might be altered.
  onGenerateRoute: (RouteSetting setting) {
    if (setting.name == '/')
      return FakeSplashRoute();
    else
      return RealRoute(setting);
  }
)

如果有更複雜的使用情境, 你可以在 MaterialAppCupertinoApp 中使用新的 API onGenerateInitialRoutes

dart
MaterialApp(
  onGenerateRoute: (RouteSetting setting) {
    return RealRoute(setting);
  },
  onGenerateInitialRoutes: (String initialRouteName) {
    return <Route>[FakeSplashRoute()];
  }
)

時程

#

合併於版本:1.16.3
正式版本釋出:1.17

參考資料

#

設計文件:

API 文件:

相關議題:

相關 PR:

  • PR 44930 - 重構命令式 API 以支援新導覽系統