Fixes page.onPopInvoked type mismatches (#153593)

fixes https://github.com/flutter/flutter/issues/153150
This commit is contained in:
chunhtai 2024-08-20 11:23:54 -07:00 committed by GitHub
parent cdab9d509b
commit e7da16df76
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 81 additions and 1 deletions

View File

@ -410,7 +410,7 @@ abstract class Route<T> extends _RoutePlaceholder {
@mustCallSuper
void onPopInvokedWithResult(bool didPop, T? result) {
if (_isPageBased) {
final Page<Object?> page = settings as Page<Object?>;
final Page<T> page = settings as Page<T>;
page.onPopInvoked(didPop, result);
}
}

View File

@ -5352,6 +5352,56 @@ void main() {
variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.android }),
skip: isBrowser, // [intended] only non-web Android supports predictive back.
);
testWidgets('canPop and onPopInvoked', (WidgetTester tester) async {
bool page2CanPop = false;
bool page3CanPop = false;
final CanPopPage<int> page1 = CanPopPage<int>(name: 'page1', pageCanPop: () => false);
final CanPopPage<String> page2 = CanPopPage<String>(name: 'page2', pageCanPop: () => page2CanPop);
final CanPopPage<bool> page3 = CanPopPage<bool>(name: 'page3', pageCanPop: () => page3CanPop);
final List<Page<Object?>> pages = <Page<Object?>>[page1, page2, page3];
final GlobalKey<NavigatorState> key = GlobalKey<NavigatorState>();
await tester.pumpWidget(
MaterialApp(
home: Navigator(
key: key,
pages: pages,
onDidRemovePage: (Page<Object?> page) => pages.remove(page),
),
),
);
expect(find.text('page3'), findsOneWidget);
key.currentState!.maybePop(true);
await tester.pumpAndSettle();
expect(find.text('page3'), findsOneWidget);
expect(page3.popInvoked, <CanPopPageInvoke>[(false, true)]);
page3CanPop = true;
key.currentState!.maybePop(false);
await tester.pumpAndSettle();
expect(find.text('page3'), findsNothing);
expect(find.text('page2'), findsOneWidget);
expect(page3.popInvoked, <CanPopPageInvoke>[(false, true), (true, false)]);
key.currentState!.maybePop('some string');
await tester.pumpAndSettle();
expect(find.text('page2'), findsOneWidget);
expect(page2.popInvoked, <CanPopPageInvoke>[(false, 'some string')]);
page2CanPop = true;
key.currentState!.maybePop('another string');
await tester.pumpAndSettle();
expect(find.text('page2'), findsNothing);
expect(find.text('page1'), findsOneWidget);
expect(page2.popInvoked, <CanPopPageInvoke>[(false, 'some string'), (true, 'another string')]);
key.currentState!.maybePop(1);
await tester.pumpAndSettle();
expect(find.text('page1'), findsOneWidget);
expect(page1.popInvoked, <CanPopPageInvoke>[(false, 1)]);
});
});
});
}
@ -5487,6 +5537,36 @@ class ZeroTransitionPage extends Page<void> {
}
}
typedef CanPopPageInvoke = (bool didPop, Object? result);
class CanPopPage<T> extends Page<T> {
CanPopPage({
super.key,
super.name,
required this.pageCanPop,
super.arguments,
});
final List<CanPopPageInvoke> popInvoked = <CanPopPageInvoke>[];
@override
bool get canPop => pageCanPop();
final ValueGetter<bool> pageCanPop;
@override
PopInvokedWithResultCallback<T> get onPopInvoked => (bool didPop, T? result) {
popInvoked.add((didPop, result));
};
@override
Route<T> createRoute(BuildContext context) {
return MaterialPageRoute<T>(
builder: (BuildContext context) => Text(name!),
settings: this,
);
}
}
class TestPage extends Page<void> {
const TestPage({
super.key,