路由過渡記錄和過渡委託更新
概述
#在路由過渡記錄中新增了一個布林型 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 頁面更新時因仍有路由等待而導致的崩潰