OverlayEntries 和 Routes 的重建优化
摘要
#此优化提高了路由过渡的性能,但可能会发现您的应用中缺少对 setState
的调用。
上下文
#在此更改之前,当在不透明条目之上添加新的不透明条目或从其上方移除时,OverlayEntry
会重建。这些重建是不必要的,因为它们不是由受影响的 OverlayEntry
的状态更改触发的。此重大更改优化了我们处理 OverlayEntry
添加和移除的方式,并删除了不必要的重建以提高性能。
由于 Navigator
在内部将每个 Route
放入 OverlayEntry
中,因此此更改也适用于 Route
过渡:如果在不透明 Route
上方推送不透明 Route
或从其上方移除,则不透明 Route
下方的 Route
不会再不必要地重建。
变更描述
#在大多数情况下,此更改不需要对您的代码进行任何更改。但是,如果您的应用错误地依赖于隐式重建,您可能会看到问题,可以通过将任何状态更改包装在 setState
调用中来解决。
此外,此更改略微修改了 widget 树的形状:在此更改之前,OverlayEntry
包裹在一个 Stack
widget 中。显式的 Stack
widget 已从 widget 层次结构中移除。
迁移指南
#如果您在升级到包含此更改的 Flutter 版本后遇到问题,请审核您的代码以查找缺少对 setState
的调用。在下面的示例中,将 Navigator.pushNamed
的返回值分配给 buttonLabel
会隐式修改状态,它应该包装在显式的 setState
调用中。
迁移前代码
class FooState extends State<Foo> {
String buttonLabel = 'Click Me';
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () async {
// Illegal state modification that should be wrapped in setState.
buttonLabel = await Navigator.pushNamed(context, '/bar');
},
child: Text(buttonLabel),
);
}
}
迁移后代码
class FooState extends State<Foo> {
String buttonLabel = 'Click Me';
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () async {
final newLabel = await Navigator.pushNamed(context, '/bar');
setState(() {
buttonLabel = newLabel;
});
},
child: Text(buttonLabel),
);
}
}
时间线
#包含于版本:1.16.3
稳定版发布:1.17
参考
#API 文档
相关问题
相关 PR
除非另有说明,否则本网站上的文档反映了 Flutter 的最新稳定版本。页面上次更新于 2024-04-04。 查看源代码 或 报告问题.