Unverified Commit 6cfb86fb authored by chunhtai's avatar chunhtai Committed by GitHub

Fix crash if update pages right after a navigator pop (#68923)

parent 27e1efc1
...@@ -985,11 +985,15 @@ class DefaultTransitionDelegate<T> extends TransitionDelegate<T> { ...@@ -985,11 +985,15 @@ class DefaultTransitionDelegate<T> extends TransitionDelegate<T> {
if (hasPagelessRoute) { if (hasPagelessRoute) {
final List<RouteTransitionRecord> pagelessRoutes = pageRouteToPagelessRoutes[exitingPageRoute]!; final List<RouteTransitionRecord> pagelessRoutes = pageRouteToPagelessRoutes[exitingPageRoute]!;
for (final RouteTransitionRecord pagelessRoute in pagelessRoutes) { for (final RouteTransitionRecord pagelessRoute in pagelessRoutes) {
assert(pagelessRoute.isWaitingForExitingDecision); // It is possible that a pageless route that belongs to an exiting
if (isLastExitingPageRoute && pagelessRoute == pagelessRoutes.last) { // page-based route does not require exiting decision. This can
pagelessRoute.markForPop(pagelessRoute.route.currentResult); // happen if the page list is updated right after a Navigator.pop.
} else { if (pagelessRoute.isWaitingForExitingDecision) {
pagelessRoute.markForComplete(pagelessRoute.route.currentResult); if (isLastExitingPageRoute && pagelessRoute == pagelessRoutes.last) {
pagelessRoute.markForPop(pagelessRoute.route.currentResult);
} else {
pagelessRoute.markForComplete(pagelessRoute.route.currentResult);
}
} }
} }
} }
...@@ -3655,7 +3659,7 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res ...@@ -3655,7 +3659,7 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res
() => <_RouteEntry>[], () => <_RouteEntry>[],
); );
pagelessRoutes.add(potentialEntryToRemove); pagelessRoutes.add(potentialEntryToRemove);
if (previousOldPageRouteEntry!.isWaitingForExitingDecision) if (previousOldPageRouteEntry!.isWaitingForExitingDecision && potentialEntryToRemove.isPresent)
potentialEntryToRemove.markNeedsExitingDecision(); potentialEntryToRemove.markNeedsExitingDecision();
continue; continue;
} }
......
...@@ -3195,6 +3195,43 @@ void main() { ...@@ -3195,6 +3195,43 @@ void main() {
expect(find.text('initial'), findsOneWidget); expect(find.text('initial'), findsOneWidget);
}); });
testWidgets('can update pages before a pageless route has finished popping', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/68162.
final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
List<Page<dynamic>> myPages = <TestPage>[
const TestPage(key: ValueKey<String>('1'), name: 'initial'),
const TestPage(key: ValueKey<String>('2'), name: 'second'),
];
bool onPopPage(Route<dynamic> route, dynamic result) {
myPages.removeWhere((Page<dynamic> page) => route.settings == page);
return route.didPop(result);
}
await tester.pumpWidget(
buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator)
);
// Pushes a pageless route.
showDialog<void>(
useRootNavigator: false,
context: navigator.currentContext!,
builder: (BuildContext context) => const Text('dialog')
);
await tester.pumpAndSettle();
expect(find.text('dialog'), findsOneWidget);
// Pops the pageless route.
navigator.currentState!.pop();
// Before the pop finishes, updates the page list.
myPages = <TestPage>[
const TestPage(key: ValueKey<String>('1'), name: 'initial'),
];
await tester.pumpWidget(
buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator)
);
// It should not crash the app.
expect(tester.takeException(), isNull);
await tester.pumpAndSettle();
expect(find.text('initial'), findsOneWidget);
});
testWidgets('pages remove and add trigger observer in the right order', (WidgetTester tester) async { testWidgets('pages remove and add trigger observer in the right order', (WidgetTester tester) async {
final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>(); final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
List<TestPage> myPages = <TestPage>[ List<TestPage> myPages = <TestPage>[
......
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