路由和导航器重构
摘要
#Route
类不再管理其覆盖层条目,并且其 install()
方法不再具有 insertionPoint
参数。RouteSetting
中的 isInitialRoute
属性已弃用,并且 Navigator.pop()
不再返回值。
上下文
#我们重构了导航器 API 以准备新的页面 API 和引入 Router
小部件,如 路由器 设计文档中所述。此重构引入了一些函数签名更改,以便使现有的导航器 API 继续与新的页面 API 一起工作。
更改说明
#Navigator.pop()
的布尔返回值定义不明确,用户可以通过调用 Navigator.canPop()
来实现相同的结果。由于 Navigator.canPop()
的 API 定义得更好,因此我们简化了 Navigator.pop()
以不返回值。
另一方面,导航器需要能够手动重新排列覆盖层中的条目,以允许用户在新的 API 中更改路由历史记录。我们更改了它,以便路由仅创建和销毁其覆盖层条目,而导航器从覆盖层中插入或删除覆盖层条目。我们还删除了 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 以在新的导航系统中继续工作
除非另有说明,否则本网站上的文档反映了 Flutter 的最新稳定版本。页面最后更新于 2024-04-04。 查看源代码 或 报告问题.