Skip to content

Commit 7755edd

Browse files
authored
Fixes a bug where NavigatorState.pop does not consider any possible s… (#150014)
�tate of the popped route fixes flutter/flutter#146938
1 parent 5eaeaca commit 7755edd

File tree

2 files changed

+62
-1
lines changed

2 files changed

+62
-1
lines changed

packages/flutter/lib/src/widgets/navigator.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5354,7 +5354,7 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res
53545354
}());
53555355
final _RouteEntry entry = _history.lastWhere(_RouteEntry.isPresentPredicate);
53565356
if (entry.pageBased && widget.onPopPage != null) {
5357-
if (widget.onPopPage!(entry.route, result) && entry.currentState == _RouteLifecycle.idle) {
5357+
if (widget.onPopPage!(entry.route, result) && entry.currentState.index <= _RouteLifecycle.idle.index) {
53585358
// The entry may have been disposed if the pop finishes synchronously.
53595359
assert(entry.route._popCompleter.isCompleted);
53605360
entry.currentState = _RouteLifecycle.pop;

packages/flutter/test/widgets/navigator_test.dart

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,67 @@ void main() {
279279
expect(observations[0].previous, 'Page 1');
280280
});
281281

282+
testWidgets('Can push, pop, and replace in sequence', (WidgetTester tester) async {
283+
const MaterialPage<void> initial = MaterialPage<void>(key: ValueKey<String>('initial'), child: Text('initial'));
284+
const MaterialPage<void> push = MaterialPage<void>(key: ValueKey<String>('push'), child: Text('push'));
285+
const MaterialPage<void> replace = MaterialPage<void>(key: ValueKey<String>('replace'), child: Text('replace'));
286+
List<Page<void>> pages = <Page<void>>[
287+
initial
288+
];
289+
bool popPageCallback(Route<dynamic> route, dynamic result) {
290+
pages.removeLast();
291+
return route.didPop(result);
292+
}
293+
final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
294+
await tester.pumpWidget(
295+
TestDependencies(
296+
child: Navigator(
297+
key: navigator,
298+
pages: pages,
299+
onPopPage: popPageCallback,
300+
),
301+
),
302+
);
303+
expect(find.text('initial'), findsOneWidget);
304+
305+
// Push a new page
306+
pages = <Page<void>>[
307+
initial,
308+
push
309+
];
310+
await tester.pumpWidget(
311+
TestDependencies(
312+
child: Navigator(
313+
key: navigator,
314+
pages: pages,
315+
onPopPage:popPageCallback,
316+
),
317+
),
318+
);
319+
await tester.pump(const Duration(milliseconds: 100));
320+
expect(find.text('push'), findsOneWidget);
321+
322+
// Pop before push finishes.
323+
navigator.currentState!.pop();
324+
325+
// Replace the entire pages
326+
// Push a new page
327+
pages = <Page<void>>[
328+
replace
329+
];
330+
await tester.pumpWidget(
331+
TestDependencies(
332+
child: Navigator(
333+
key: navigator,
334+
pages: pages,
335+
onPopPage:popPageCallback,
336+
),
337+
),
338+
);
339+
await tester.pumpAndSettle();
340+
expect(find.text('replace'), findsOneWidget);
341+
});
342+
282343
testWidgets('Navigator.of rootNavigator finds root Navigator', (WidgetTester tester) async {
283344
await tester.pumpWidget(MaterialApp(
284345
home: Material(

0 commit comments

Comments
 (0)