概述

#

`route transition record` 新增了一个布尔型 getter `isWaitingForExitingDecision`,并且 `isEntering` getter 已重命名为 `isWaitingForEnteringDecision`。在过渡委托的 `resolve()` 方法中,使用 `isWaitingForExitingDecision` 来检查退出路由是否确实需要明确的决策来如何退出屏幕。如果您尝试为一个*不需要*决策的现有路由做出决策,Flutter 将抛出断言错误。

背景

#

当导航器接收到新的页面列表时,它会尝试更新其当前的路由堆栈以匹配该列表。然而,这需要明确的决策来如何让路由进入和退出屏幕。以前,不在新列表中的路由需要关于如何退出屏幕的决策。然而,我们后来发现这并非总是如此。如果一个路由被弹出,但仍在等待弹出动画完成,该路由将停留在导航器路由堆栈中,直到动画完成。如果在此期间发生页面更新,此路由会退出,但不需要关于如何退出屏幕的决策。因此,添加了 `isWaitingForExitingDecision` 来涵盖这种情况。

`isEntering` getter 也重命名为 `isWaitingForEnteringDecision`,以使其更具描述性,并使命名更一致。

迁移指南

#

如果您实现自己的过渡委托,您需要在调用 `markForPop`、`markForComplete` 或 `markForRemove` 之前,使用 getter `isWaitingForExitingDecision` 检查退出路由。您还需要将所有对 `isEntering` 的引用重命名为 `isWaitingForEnteringDecision`。

迁移前的代码

dart
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;
  }
}

迁移后的代码

dart
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: 修复了当仍有路由等待时导航器页面更新崩溃的问题