Fix RouterObserver didPop is not called when reverseTransitionDuratio… (#97171)
This commit is contained in:
parent
2787eb0269
commit
185bc093e0
@ -5023,11 +5023,15 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res
|
||||
bool? wasDebugLocked;
|
||||
assert(() { wasDebugLocked = _debugLocked; _debugLocked = true; return true; }());
|
||||
assert(_history.where(_RouteEntry.isRoutePredicate(route)).length == 1);
|
||||
final _RouteEntry entry = _history.firstWhere(_RouteEntry.isRoutePredicate(route));
|
||||
// For page-based route, the didPop can be called on any life cycle above
|
||||
// pop.
|
||||
assert(entry.currentState == _RouteLifecycle.popping ||
|
||||
(entry.hasPage && entry.currentState.index < _RouteLifecycle.pop.index));
|
||||
final int index = _history.indexWhere(_RouteEntry.isRoutePredicate(route));
|
||||
final _RouteEntry entry = _history[index];
|
||||
// For page-based route with zero transition, the finalizeRoute can be
|
||||
// called on any life cycle above pop.
|
||||
if (entry.hasPage && entry.currentState.index < _RouteLifecycle.pop.index) {
|
||||
_observedRouteDeletions.add(_NavigatorPopObservation(route, _getRouteBefore(index - 1, _RouteEntry.willBePresentPredicate)?.route));
|
||||
} else {
|
||||
assert(entry.currentState == _RouteLifecycle.popping);
|
||||
}
|
||||
entry.finalize();
|
||||
// finalizeRoute can be called during _flushHistoryUpdates if a pop
|
||||
// finishes synchronously.
|
||||
|
@ -183,6 +183,47 @@ void main() {
|
||||
expect('$exception', startsWith('Navigator operation requested with a context'));
|
||||
});
|
||||
|
||||
testWidgets('Zero transition page-based route correctly notifies observers when it is popped', (WidgetTester tester) async {
|
||||
final List<Page<void>> pages = <Page<void>>[
|
||||
const ZeroTransitionPage(name: 'Page 1'),
|
||||
const ZeroTransitionPage(name: 'Page 2'),
|
||||
];
|
||||
final List<NavigatorObservation> observations = <NavigatorObservation>[];
|
||||
|
||||
final TestObserver observer = TestObserver()
|
||||
..onPopped = (Route<dynamic>? route, Route<dynamic>? previousRoute) {
|
||||
observations.add(
|
||||
NavigatorObservation(
|
||||
current: route?.settings.name,
|
||||
previous: previousRoute?.settings.name,
|
||||
operation: 'pop',
|
||||
),
|
||||
);
|
||||
};
|
||||
final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: Navigator(
|
||||
key: navigator,
|
||||
pages: pages,
|
||||
observers: <NavigatorObserver>[observer],
|
||||
onPopPage: (Route<dynamic> route, dynamic result) {
|
||||
pages.removeLast();
|
||||
return route.didPop(result);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
navigator.currentState!.pop();
|
||||
await tester.pump();
|
||||
|
||||
expect(observations.length, 1);
|
||||
expect(observations[0].current, 'Page 2');
|
||||
expect(observations[0].previous, 'Page 1');
|
||||
});
|
||||
|
||||
testWidgets('Navigator.of rootNavigator finds root Navigator', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Material(
|
||||
@ -3941,6 +3982,22 @@ class AlwaysRemoveTransitionDelegate extends TransitionDelegate<void> {
|
||||
}
|
||||
}
|
||||
|
||||
class ZeroTransitionPage extends Page<void> {
|
||||
const ZeroTransitionPage({
|
||||
LocalKey? key,
|
||||
Object? arguments,
|
||||
required String name,
|
||||
}) : super(key: key, name: name, arguments: arguments);
|
||||
|
||||
@override
|
||||
Route<void> createRoute(BuildContext context) {
|
||||
return NoAnimationPageRoute(
|
||||
settings: this,
|
||||
pageBuilder: (BuildContext context) => Text(name!),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class TestPage extends Page<void> {
|
||||
const TestPage({
|
||||
LocalKey? key,
|
||||
@ -3958,15 +4015,17 @@ class TestPage extends Page<void> {
|
||||
}
|
||||
|
||||
class NoAnimationPageRoute extends PageRouteBuilder<void> {
|
||||
NoAnimationPageRoute({required WidgetBuilder pageBuilder})
|
||||
: super(pageBuilder: (BuildContext context, __, ___) {
|
||||
return pageBuilder(context);
|
||||
});
|
||||
|
||||
@override
|
||||
AnimationController createAnimationController() {
|
||||
return super.createAnimationController()..value = 1.0;
|
||||
}
|
||||
NoAnimationPageRoute({
|
||||
RouteSettings? settings,
|
||||
required WidgetBuilder pageBuilder
|
||||
}) : super(
|
||||
settings: settings,
|
||||
transitionDuration: Duration.zero,
|
||||
reverseTransitionDuration: Duration.zero,
|
||||
pageBuilder: (BuildContext context, __, ___) {
|
||||
return pageBuilder(context);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
class StatefulTestWidget extends StatefulWidget {
|
||||
|
Loading…
x
Reference in New Issue
Block a user