Skip to content

Commit c98978a

Browse files
hannah-hyjchunhtai
andauthored
Update Navigator updatePages() (#116945)
* Update navigator.dart * Update navigator.dart * Add test * Update navigator.dart * lint * Update packages/flutter/test/widgets/navigator_test.dart Co-authored-by: chunhtai <[email protected]> * Update packages/flutter/test/widgets/navigator_test.dart Co-authored-by: chunhtai <[email protected]> Co-authored-by: chunhtai <[email protected]>
1 parent 91c1c70 commit c98978a

File tree

2 files changed

+69
-7
lines changed

2 files changed

+69
-7
lines changed

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

+14-7
Original file line numberDiff line numberDiff line change
@@ -3687,30 +3687,37 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res
36873687
oldEntriesBottom += 1;
36883688
}
36893689

3690-
int pagelessRoutesToSkip = 0;
3690+
final List<_RouteEntry> unattachedPagelessRoutes=<_RouteEntry>[];
36913691
// Scans the top of the list until we found a page-based route that cannot be
36923692
// updated.
36933693
while ((oldEntriesBottom <= oldEntriesTop) && (newPagesBottom <= newPagesTop)) {
36943694
final _RouteEntry oldEntry = _history[oldEntriesTop];
36953695
assert(oldEntry != null && oldEntry.currentState != _RouteLifecycle.disposed);
36963696
if (!oldEntry.pageBased) {
3697-
// This route might need to be skipped if we can not find a page above.
3698-
pagelessRoutesToSkip += 1;
3697+
unattachedPagelessRoutes.add(oldEntry);
36993698
oldEntriesTop -= 1;
37003699
continue;
37013700
}
37023701
final Page<dynamic> newPage = widget.pages[newPagesTop];
37033702
if (!oldEntry.canUpdateFrom(newPage)) {
37043703
break;
37053704
}
3706-
// We found the page for all the consecutive pageless routes below. Those
3707-
// pageless routes do not need to be skipped.
3708-
pagelessRoutesToSkip = 0;
3705+
3706+
// We found the page for all the consecutive pageless routes below. Attach these
3707+
// pageless routes to the page.
3708+
if(unattachedPagelessRoutes.isNotEmpty) {
3709+
pageRouteToPagelessRoutes.putIfAbsent(
3710+
oldEntry,
3711+
() => List<_RouteEntry>.from(unattachedPagelessRoutes),
3712+
);
3713+
unattachedPagelessRoutes.clear();
3714+
}
3715+
37093716
oldEntriesTop -= 1;
37103717
newPagesTop -= 1;
37113718
}
37123719
// Reverts the pageless routes that cannot be updated.
3713-
oldEntriesTop += pagelessRoutesToSkip;
3720+
oldEntriesTop += unattachedPagelessRoutes.length;
37143721

37153722
// Scans middle of the old entries and records the page key to old entry map.
37163723
int oldEntriesBottomToScan = oldEntriesBottom;

packages/flutter/test/widgets/navigator_test.dart

+55
Original file line numberDiff line numberDiff line change
@@ -3342,6 +3342,61 @@ void main() {
33423342
expect(find.text('forth'), findsOneWidget);
33433343
});
33443344

3345+
//Regression test for https://github.com/flutter/flutter/issues/115887
3346+
testWidgets('Complex case 2', (WidgetTester tester) async {
3347+
final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
3348+
List<TestPage> myPages = <TestPage>[
3349+
const TestPage(key: ValueKey<String>('1'), name:'initial'),
3350+
const TestPage(key: ValueKey<String>('2'), name:'second'),
3351+
];
3352+
3353+
bool onPopPage(Route<dynamic> route, dynamic result) {
3354+
myPages.removeWhere((Page<dynamic> page) => route.settings == page);
3355+
return route.didPop(result);
3356+
}
3357+
3358+
await tester.pumpWidget(
3359+
buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator),
3360+
);
3361+
expect(find.text('second'), findsOneWidget);
3362+
expect(find.text('initial'), findsNothing);
3363+
// Push pageless route to second page route
3364+
navigator.currentState!.push(
3365+
MaterialPageRoute<void>(
3366+
builder: (BuildContext context) => const Text('second-pageless1'),
3367+
),
3368+
);
3369+
3370+
await tester.pumpAndSettle();
3371+
// Now the history should look like [initial, second, second-pageless1].
3372+
expect(find.text('initial'), findsNothing);
3373+
expect(find.text('second'), findsNothing);
3374+
expect(find.text('second-pageless1'), findsOneWidget);
3375+
expect(myPages.length, 2);
3376+
3377+
myPages = <TestPage>[
3378+
const TestPage(key: ValueKey<String>('2'), name:'second'),
3379+
];
3380+
await tester.pumpWidget(
3381+
buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator),
3382+
);
3383+
await tester.pumpAndSettle();
3384+
3385+
// Now the history should look like [second, second-pageless1].
3386+
expect(find.text('initial'), findsNothing);
3387+
expect(find.text('second'), findsNothing);
3388+
expect(find.text('second-pageless1'), findsOneWidget);
3389+
expect(myPages.length, 1);
3390+
3391+
// Pop the pageless route.
3392+
navigator.currentState!.pop();
3393+
await tester.pumpAndSettle();
3394+
expect(myPages.length, 1);
3395+
expect(find.text('initial'), findsNothing);
3396+
expect(find.text('second'), findsOneWidget);
3397+
expect(find.text('second-pageless1'), findsNothing);
3398+
});
3399+
33453400
testWidgets('complex case 1 - with always remove transition delegate', (WidgetTester tester) async {
33463401
final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
33473402
final AlwaysRemoveTransitionDelegate transitionDelegate = AlwaysRemoveTransitionDelegate();

0 commit comments

Comments
 (0)