路由與導航器重構
概述
#Route 類不再在其 overlay 中管理自己的 overlay entries,其 install() 方法也不再帶有 insertionPoint 引數。RouteSetting 中的 isInitialRoute 屬性已被棄用,並且 Navigator.pop() 不再返回值。
背景
#我們重構了導航器 API,以支援新的頁面 API 和 Router 設計文件中概述的 Router widget 的引入。此重構引入了一些函式簽名更改,以便現有的導航器 API 能夠與新的頁面 API 繼續協同工作。
變更說明
#Navigator.pop() 的布林返回值定義不明確,使用者可以透過呼叫 Navigator.canPop() 來達到相同的結果。由於 Navigator.canPop() 的 API 定義更清晰,我們簡化了 Navigator.pop(),使其不返回值。
另一方面,為了使使用者能夠在新的 API 中更改路由歷史,導航器需要能夠手動重新排列 overlay 中的條目。我們進行了更改,使其路由僅建立和銷燬其 overlay entries,而導航器負責將 overlay entries 插入或移除 overlay。我們還移除了 Route.install() 的 insertionPoint 引數,因為它在更改後已過時。
最後,作為重構的一部分,我們從 RouteSetting 中移除了 isInitialRoute 屬性,並提供了 onGenerateInitialRoutes API 來完全控制初始路由的生成。
遷移指南
#情況 1:應用程式依賴於 pop() 返回布林值。
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() 來達到相同的結果。
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 生成路由。
MaterialApp(
onGenerateRoute: (RouteSetting setting) {
if (setting.isInitialRoute)
return FakeSplashRoute();
else
return RealRoute(setting);
}
)有多種方法可以遷移此更改。一種方法是為 MaterialApp.initialRoute 設定顯式值。然後,您可以在程式碼中測試此值來代替 isInitialRoute。由於 initialRoute 繼承其預設值(在 Flutter 範圍之外),因此您必須為其設定一個顯式值。
MaterialApp(
initialRoute: '/', // Set this value explicitly. Default might be altered.
onGenerateRoute: (RouteSetting setting) {
if (setting.name == '/')
return FakeSplashRoute();
else
return RealRoute(setting);
}
)如果存在更復雜的用例,您可以在 MaterialApp 或 CupertinoApp 中使用新的 API onGenerateInitialRoutes。
MaterialApp(
onGenerateRoute: (RouteSetting setting) {
return RealRoute(setting);
},
onGenerateInitialRoutes: (String initialRouteName) {
return <Route>[FakeSplashRoute()];
}
)時間線
#釋出版本: 1.16.3
穩定版本: 1.17
參考資料
#設計文件
API 文件
相關議題
相關 PR
- PR 44930 - 重構命令式 API 以在新導航系統中繼續工作