Unverified Commit 185bc093 authored by chunhtai's avatar chunhtai Committed by GitHub

Fix RouterObserver didPop is not called when reverseTransitionDuratio… (#97171)

parent 2787eb02
......@@ -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 {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment