Unverified Commit c98978ae authored by hangyu's avatar hangyu Committed by GitHub

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: 's avatarchunhtai <47866232+chunhtai@users.noreply.github.com>

* Update packages/flutter/test/widgets/navigator_test.dart
Co-authored-by: 's avatarchunhtai <47866232+chunhtai@users.noreply.github.com>
Co-authored-by: 's avatarchunhtai <47866232+chunhtai@users.noreply.github.com>
parent 91c1c70b
......@@ -3687,15 +3687,14 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res
oldEntriesBottom += 1;
}
int pagelessRoutesToSkip = 0;
final List<_RouteEntry> unattachedPagelessRoutes=<_RouteEntry>[];
// Scans the top of the list until we found a page-based route that cannot be
// updated.
while ((oldEntriesBottom <= oldEntriesTop) && (newPagesBottom <= newPagesTop)) {
final _RouteEntry oldEntry = _history[oldEntriesTop];
assert(oldEntry != null && oldEntry.currentState != _RouteLifecycle.disposed);
if (!oldEntry.pageBased) {
// This route might need to be skipped if we can not find a page above.
pagelessRoutesToSkip += 1;
unattachedPagelessRoutes.add(oldEntry);
oldEntriesTop -= 1;
continue;
}
......@@ -3703,14 +3702,22 @@ class NavigatorState extends State<Navigator> with TickerProviderStateMixin, Res
if (!oldEntry.canUpdateFrom(newPage)) {
break;
}
// We found the page for all the consecutive pageless routes below. Those
// pageless routes do not need to be skipped.
pagelessRoutesToSkip = 0;
// We found the page for all the consecutive pageless routes below. Attach these
// pageless routes to the page.
if(unattachedPagelessRoutes.isNotEmpty) {
pageRouteToPagelessRoutes.putIfAbsent(
oldEntry,
() => List<_RouteEntry>.from(unattachedPagelessRoutes),
);
unattachedPagelessRoutes.clear();
}
oldEntriesTop -= 1;
newPagesTop -= 1;
}
// Reverts the pageless routes that cannot be updated.
oldEntriesTop += pagelessRoutesToSkip;
oldEntriesTop += unattachedPagelessRoutes.length;
// Scans middle of the old entries and records the page key to old entry map.
int oldEntriesBottomToScan = oldEntriesBottom;
......
......@@ -3342,6 +3342,61 @@ void main() {
expect(find.text('forth'), findsOneWidget);
});
//Regression test for https://github.com/flutter/flutter/issues/115887
testWidgets('Complex case 2', (WidgetTester tester) async {
final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
List<TestPage> 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),
);
expect(find.text('second'), findsOneWidget);
expect(find.text('initial'), findsNothing);
// Push pageless route to second page route
navigator.currentState!.push(
MaterialPageRoute<void>(
builder: (BuildContext context) => const Text('second-pageless1'),
),
);
await tester.pumpAndSettle();
// Now the history should look like [initial, second, second-pageless1].
expect(find.text('initial'), findsNothing);
expect(find.text('second'), findsNothing);
expect(find.text('second-pageless1'), findsOneWidget);
expect(myPages.length, 2);
myPages = <TestPage>[
const TestPage(key: ValueKey<String>('2'), name:'second'),
];
await tester.pumpWidget(
buildNavigator(pages: myPages, onPopPage: onPopPage, key: navigator),
);
await tester.pumpAndSettle();
// Now the history should look like [second, second-pageless1].
expect(find.text('initial'), findsNothing);
expect(find.text('second'), findsNothing);
expect(find.text('second-pageless1'), findsOneWidget);
expect(myPages.length, 1);
// Pop the pageless route.
navigator.currentState!.pop();
await tester.pumpAndSettle();
expect(myPages.length, 1);
expect(find.text('initial'), findsNothing);
expect(find.text('second'), findsOneWidget);
expect(find.text('second-pageless1'), findsNothing);
});
testWidgets('complex case 1 - with always remove transition delegate', (WidgetTester tester) async {
final GlobalKey<NavigatorState> navigator = GlobalKey<NavigatorState>();
final AlwaysRemoveTransitionDelegate transitionDelegate = AlwaysRemoveTransitionDelegate();
......
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