mirror of
https://github.com/flutter/flutter
synced 2024-10-13 11:42:54 +00:00
Allow WIllPopCallback to return null or false to veto the pop. (#54640)
This commit is contained in:
parent
d1e052815e
commit
ff2358623b
|
@ -1239,9 +1239,11 @@ abstract class ModalRoute<T> extends TransitionRoute<T> with LocalHistoryRoute<T
|
|||
|
||||
final List<WillPopCallback> _willPopCallbacks = <WillPopCallback>[];
|
||||
|
||||
/// Returns the value of the first callback added with
|
||||
/// [addScopedWillPopCallback] that returns false. If they all return true,
|
||||
/// returns the inherited method's result (see [Route.willPop]).
|
||||
/// Returns [RoutePopDisposition.doNotPop] if any of callbacks added with
|
||||
/// [addScopedWillPopCallback] returns either false or null. If they all
|
||||
/// return true, the base [Route.willPop]'s result will be returned. The
|
||||
/// callbacks will be called in the order they were added, and will only be
|
||||
/// called if all previous callbacks returned true.
|
||||
///
|
||||
/// Typically this method is not overridden because applications usually
|
||||
/// don't create modal routes directly, they use higher level primitives
|
||||
|
@ -1260,7 +1262,7 @@ abstract class ModalRoute<T> extends TransitionRoute<T> with LocalHistoryRoute<T
|
|||
final _ModalScopeState<T> scope = _scopeKey.currentState;
|
||||
assert(scope != null);
|
||||
for (final WillPopCallback callback in List<WillPopCallback>.from(_willPopCallbacks)) {
|
||||
if (!await callback())
|
||||
if (await callback() != true)
|
||||
return RoutePopDisposition.doNotPop;
|
||||
}
|
||||
return await super.willPop();
|
||||
|
|
|
@ -128,6 +128,51 @@ void main() {
|
|||
expect(find.text('Sample Page'), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('willPop will only pop if the callback returns true', (WidgetTester tester) async {
|
||||
Widget buildFrame() {
|
||||
return MaterialApp(
|
||||
home: Scaffold(
|
||||
appBar: AppBar(title: const Text('Home')),
|
||||
body: Builder(
|
||||
builder: (BuildContext context) {
|
||||
return Center(
|
||||
child: FlatButton(
|
||||
child: const Text('X'),
|
||||
onPressed: () {
|
||||
Navigator.of(context).push(MaterialPageRoute<void>(
|
||||
builder: (BuildContext context) {
|
||||
return SampleForm(
|
||||
callback: () => Future<bool>.value(willPopValue),
|
||||
);
|
||||
},
|
||||
));
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
await tester.pumpWidget(buildFrame());
|
||||
await tester.tap(find.text('X'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('Sample Form'), findsOneWidget);
|
||||
|
||||
// Should not pop if callback returns null
|
||||
willPopValue = null;
|
||||
await tester.tap(find.byTooltip('Back'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('Sample Form'), findsOneWidget);
|
||||
|
||||
// Should pop if callback returns true
|
||||
willPopValue = true;
|
||||
await tester.tap(find.byTooltip('Back'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('Sample Form'), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('Form.willPop can inhibit back button', (WidgetTester tester) async {
|
||||
Widget buildFrame() {
|
||||
return MaterialApp(
|
||||
|
|
Loading…
Reference in a new issue