路由过渡记录和过渡委托更新
概述
#在路由过渡记录中新增了一个布尔型 getter `isWaitingForExitingDecision`,并将 `isEntering` getter 重命名为 `isWaitingForEnteringDecision`。在过渡委托的 `resolve()` 方法中,使用 `isWaitingForExitingDecision` 来检查一个退出的路由是否真的需要一个明确的屏幕过渡决定。如果你尝试为一个不需要决定的退出路由做出决定,Flutter 会抛出断言错误。
背景
#当 Navigator 收到新的页面列表时,它会尝试更新其当前的路由堆栈以匹配该列表。然而,这需要明确的屏幕进入和退出过渡决定。之前,不在新列表中的路由需要退出过渡决定。但后来我们发现这并非总是如此。如果一个路由被 popped,但仍在等待退出动画完成,该路由会留在 Navigator 的路由堆栈中直到动画完成。如果在此期间发生了页面更新,该路由会退出,但不需要屏幕退出过渡决定。因此,添加了 `isWaitingForExitingDecision` 来涵盖这种情况。
`isEntering` getter 也被重命名为 `isWaitingForEnteringDecision`,以便更具描述性,并使命名更一致。
迁移指南
#如果你实现了自己的过渡委托,在对退出路由调用 `markForPop`、`markForComplete` 或 `markForRemove` 之前,你需要使用 `isWaitingForExitingDecision` getter 来检查它们。你还需要将所有对 `isEntering` 的引用重命名为 `isWaitingForEnteringDecision`。
迁移前的代码
import 'package:flutter/widgets.dart';
class NoAnimationTransitionDelegate extends TransitionDelegate<void> {
@override
Iterable<RouteTransitionRecord> resolve({
List<RouteTransitionRecord> newPageRouteHistory,
Map<RouteTransitionRecord, RouteTransitionRecord> locationToExitingPageRoute,
Map<RouteTransitionRecord, List<RouteTransitionRecord>> pageRouteToPagelessRoutes,
}) {
final List<RouteTransitionRecord> results = <RouteTransitionRecord>[];
for (final RouteTransitionRecord pageRoute in newPageRouteHistory) {
if (pageRoute.isEntering) {
pageRoute.markForAdd();
}
results.add(pageRoute);
}
for (final RouteTransitionRecord exitingPageRoute in locationToExitingPageRoute.values) {
exitingPageRoute.markForRemove();
final List<RouteTransitionRecord> pagelessRoutes = pageRouteToPagelessRoutes[exitingPageRoute];
if (pagelessRoutes != null) {
for (final RouteTransitionRecord pagelessRoute in pagelessRoutes) {
pagelessRoute.markForRemove();
}
}
results.add(exitingPageRoute);
}
return results;
}
}
迁移后的代码
import 'package:flutter/widgets.dart';
class NoAnimationTransitionDelegate extends TransitionDelegate<void> {
@override
Iterable<RouteTransitionRecord> resolve({
List<RouteTransitionRecord> newPageRouteHistory,
Map<RouteTransitionRecord, RouteTransitionRecord> locationToExitingPageRoute,
Map<RouteTransitionRecord, List<RouteTransitionRecord>> pageRouteToPagelessRoutes,
}) {
final List<RouteTransitionRecord> results = <RouteTransitionRecord>[];
for (final RouteTransitionRecord pageRoute in newPageRouteHistory) {
// Renames isEntering to isWaitingForEnteringDecision.
if (pageRoute.isWaitingForEnteringDecision) {
pageRoute.markForAdd();
}
results.add(pageRoute);
}
for (final RouteTransitionRecord exitingPageRoute in locationToExitingPageRoute.values) {
// Checks the isWaitingForExitingDecision before calling the markFor methods.
if (exitingPageRoute.isWaitingForExitingDecision) {
exitingPageRoute.markForRemove();
final List<RouteTransitionRecord> pagelessRoutes = pageRouteToPagelessRoutes[exitingPageRoute];
if (pagelessRoutes != null) {
for (final RouteTransitionRecord pagelessRoute in pagelessRoutes) {
pagelessRoute.markForRemove();
}
}
}
results.add(exitingPageRoute);
}
return results;
}
}
时间线
#发布版本:1.18.0
稳定版本中:1.20
参考资料
#API 文档
相关议题
相关 PR
- PR 55998: 修复 Navigator 页面更新时因仍有路由等待而导致的崩溃