路由与导航器重构
概述
#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 以在新导航系统中继续工作