Expose barrierDismissible in PageRoute constructor (#133659)
## Description This PR exposes `barrierDismissible` in `PageRoute`, `MaterialPageRoute` and `CupertinoPageRoute` constructors. Setting this property to true will enable the escape key binding. ## Related Issue Fixes https://github.com/flutter/flutter/issues/132138. ## Tests Adds one test.
This commit is contained in:
parent
15048a6b04
commit
b23105276f
@ -311,6 +311,9 @@ mixin CupertinoRouteTransitionMixin<T> on PageRoute<T> {
|
|||||||
/// the route is popped from the stack via [Navigator.pop] when an optional
|
/// the route is popped from the stack via [Navigator.pop] when an optional
|
||||||
/// `result` can be provided.
|
/// `result` can be provided.
|
||||||
///
|
///
|
||||||
|
/// If `barrierDismissible` is true, then pressing the escape key on the keyboard
|
||||||
|
/// will cause the current route to be popped with null as the value.
|
||||||
|
///
|
||||||
/// See also:
|
/// See also:
|
||||||
///
|
///
|
||||||
/// * [CupertinoRouteTransitionMixin], for a mixin that provides iOS transition
|
/// * [CupertinoRouteTransitionMixin], for a mixin that provides iOS transition
|
||||||
@ -334,6 +337,7 @@ class CupertinoPageRoute<T> extends PageRoute<T> with CupertinoRouteTransitionMi
|
|||||||
this.maintainState = true,
|
this.maintainState = true,
|
||||||
super.fullscreenDialog,
|
super.fullscreenDialog,
|
||||||
super.allowSnapshotting = true,
|
super.allowSnapshotting = true,
|
||||||
|
super.barrierDismissible = false,
|
||||||
}) {
|
}) {
|
||||||
assert(opaque);
|
assert(opaque);
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,9 @@ import 'theme.dart';
|
|||||||
/// fullscreen modal dialog. On iOS, those routes animate from the bottom to the
|
/// fullscreen modal dialog. On iOS, those routes animate from the bottom to the
|
||||||
/// top rather than horizontally.
|
/// top rather than horizontally.
|
||||||
///
|
///
|
||||||
|
/// If `barrierDismissible` is true, then pressing the escape key on the keyboard
|
||||||
|
/// will cause the current route to be popped with null as the value.
|
||||||
|
///
|
||||||
/// The type `T` specifies the return type of the route which can be supplied as
|
/// The type `T` specifies the return type of the route which can be supplied as
|
||||||
/// the route is popped from the stack via [Navigator.pop] by providing the
|
/// the route is popped from the stack via [Navigator.pop] by providing the
|
||||||
/// optional `result` argument.
|
/// optional `result` argument.
|
||||||
@ -40,6 +43,7 @@ class MaterialPageRoute<T> extends PageRoute<T> with MaterialRouteTransitionMixi
|
|||||||
this.maintainState = true,
|
this.maintainState = true,
|
||||||
super.fullscreenDialog,
|
super.fullscreenDialog,
|
||||||
super.allowSnapshotting = true,
|
super.allowSnapshotting = true,
|
||||||
|
super.barrierDismissible = false,
|
||||||
}) {
|
}) {
|
||||||
assert(opaque);
|
assert(opaque);
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,9 @@ import 'routes.dart';
|
|||||||
/// The [PageRouteBuilder] subclass provides a way to create a [PageRoute] using
|
/// The [PageRouteBuilder] subclass provides a way to create a [PageRoute] using
|
||||||
/// callbacks rather than by defining a new class via subclassing.
|
/// callbacks rather than by defining a new class via subclassing.
|
||||||
///
|
///
|
||||||
|
/// If `barrierDismissible` is true, then pressing the escape key on the keyboard
|
||||||
|
/// will cause the current route to be popped with null as the value.
|
||||||
|
///
|
||||||
/// See also:
|
/// See also:
|
||||||
///
|
///
|
||||||
/// * [Route], which documents the meaning of the `T` generic type argument.
|
/// * [Route], which documents the meaning of the `T` generic type argument.
|
||||||
@ -20,7 +23,8 @@ abstract class PageRoute<T> extends ModalRoute<T> {
|
|||||||
super.settings,
|
super.settings,
|
||||||
this.fullscreenDialog = false,
|
this.fullscreenDialog = false,
|
||||||
this.allowSnapshotting = true,
|
this.allowSnapshotting = true,
|
||||||
});
|
bool barrierDismissible = false,
|
||||||
|
}) : _barrierDismissible = barrierDismissible;
|
||||||
|
|
||||||
/// {@template flutter.widgets.PageRoute.fullscreenDialog}
|
/// {@template flutter.widgets.PageRoute.fullscreenDialog}
|
||||||
/// Whether this page route is a full-screen dialog.
|
/// Whether this page route is a full-screen dialog.
|
||||||
@ -39,7 +43,8 @@ abstract class PageRoute<T> extends ModalRoute<T> {
|
|||||||
bool get opaque => true;
|
bool get opaque => true;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool get barrierDismissible => false;
|
bool get barrierDismissible => _barrierDismissible;
|
||||||
|
final bool _barrierDismissible;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool canTransitionTo(TransitionRoute<dynamic> nextRoute) => nextRoute is PageRoute;
|
bool canTransitionTo(TransitionRoute<dynamic> nextRoute) => nextRoute is PageRoute;
|
||||||
|
@ -11,6 +11,7 @@ import 'package:flutter/cupertino.dart' show CupertinoPageRoute;
|
|||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/rendering.dart';
|
import 'package:flutter/rendering.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
@ -1229,6 +1230,45 @@ void main() {
|
|||||||
expect(find.text('p1'), findsOneWidget);
|
expect(find.text('p1'), findsOneWidget);
|
||||||
expect(find.text('count: 1'), findsOneWidget);
|
expect(find.text('count: 1'), findsOneWidget);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('MaterialPageRoute can be dismissed with escape keyboard shortcut', (WidgetTester tester) async {
|
||||||
|
// Regression test for https://github.com/flutter/flutter/issues/132138.
|
||||||
|
final GlobalKey scaffoldKey = GlobalKey();
|
||||||
|
|
||||||
|
await tester.pumpWidget(
|
||||||
|
MaterialApp(
|
||||||
|
home: Scaffold(
|
||||||
|
key: scaffoldKey,
|
||||||
|
body: Center(
|
||||||
|
child: ElevatedButton(
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.push<void>(scaffoldKey.currentContext!, MaterialPageRoute<void>(
|
||||||
|
builder: (BuildContext context) {
|
||||||
|
return const Scaffold(
|
||||||
|
body: Center(child: Text('route')),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
barrierDismissible: true,
|
||||||
|
));
|
||||||
|
},
|
||||||
|
child: const Text('push'),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
await tester.tap(find.text('push'));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
expect(find.text('route'), findsOneWidget);
|
||||||
|
expect(find.text('push'), findsNothing);
|
||||||
|
|
||||||
|
// Try to dismiss the route with the escape key.
|
||||||
|
await tester.sendKeyEvent(LogicalKeyboardKey.escape);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
expect(find.text('route'), findsNothing);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
class TransitionDetector extends DefaultTransitionDelegate<void> {
|
class TransitionDetector extends DefaultTransitionDelegate<void> {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user