Actualizaciones del registro de transición de ruta y del transition delegate
Cambios en la regla sobre cómo el transition delegate resuelve la transición de ruta.
Resumen
#Se añadió un nuevo getter booleano isWaitingForExitingDecision
al registro de transición de ruta y el getter isEntering
se renombró a isWaitingForEnteringDecision.
En el método resolve() para el transition delegate,
usa isWaitingForExitingDecision para verificar si una ruta
de salida realmente necesita una decisión explícita sobre cómo transicionar
fuera de la pantalla. Si intentas tomar una decisión para una ruta existente
que no está esperando una decisión, Flutter lanzará un error de aserción.
Contexto
#Cuando el navigator recibe una nueva lista de pages, intenta actualizar su
pila de rutas actual para que coincida con la lista. Sin embargo, requiere decisiones
explícitas sobre cómo transicionar la ruta hacia y fuera de la pantalla.
Anteriormente, las rutas que no estaban en la nueva lista requerían decisiones
sobre cómo transicionar fuera de la pantalla. Sin embargo, más tarde descubrimos
que esto no siempre es así. Si una ruta se hace pop,
pero aún está esperando que termine la animación de pop,
esta ruta permanecería en la pila de rutas del navigator hasta
que terminara la animación. Si ocurriera una actualización de page durante este tiempo,
esta ruta saldría pero no requeriría una decisión
sobre cómo transicionar fuera de la pantalla. Por lo tanto,
se añadió isWaitingForExitingDecision para cubrir ese caso.
El getter isEntering también se renombró a
isWaitingForEnteringDecision para ser más descriptivo,
y también para hacer que la nomenclatura sea más consistente.
Guía de migración
#Si implementas tu propio transition delegate, necesitas verificar las
rutas salientes usando el getter isWaitingForExitingDecision antes de
llamar a markForPop, markForComplete o markForRemove
en ellas.
También necesitas renombrar todas las referencias de isEntering a
isWaitingForEnteringDecision.
Código antes de la migración:
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;
}
}
Código después de la migración:
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;
}
}
Timeline
#Introducido en la versión: 1.18.0
En la versión estable: 1.20
Referencias
#Documentación de la API:
Problema relevante:
PR relevante:
- PR 55998: Corrige el fallo de actualización de pages del navigator cuando todavía hay una ruta esperando
A menos que se indique lo contrario, la documentación de este sitio refleja Flutter 3.44.0. Página actualizada por última vez el 2026-05-05. Ver código fuente oreportar un problema.