mirror of
https://github.com/flutter/flutter
synced 2024-10-13 11:42:54 +00:00
Add enableDrag configuration for showModalBottomSheet (#46685)
This commit is contained in:
parent
c06bf6503a
commit
fba96809f4
|
@ -265,7 +265,9 @@ class _ModalBottomSheet<T> extends StatefulWidget {
|
|||
this.shape,
|
||||
this.clipBehavior,
|
||||
this.isScrollControlled = false,
|
||||
this.enableDrag = true,
|
||||
}) : assert(isScrollControlled != null),
|
||||
assert(enableDrag != null),
|
||||
super(key: key);
|
||||
|
||||
final _ModalBottomSheetRoute<T> route;
|
||||
|
@ -274,6 +276,7 @@ class _ModalBottomSheet<T> extends StatefulWidget {
|
|||
final double elevation;
|
||||
final ShapeBorder shape;
|
||||
final Clip clipBehavior;
|
||||
final bool enableDrag;
|
||||
|
||||
@override
|
||||
_ModalBottomSheetState<T> createState() => _ModalBottomSheetState<T>();
|
||||
|
@ -326,6 +329,7 @@ class _ModalBottomSheetState<T> extends State<_ModalBottomSheet<T>> {
|
|||
elevation: widget.elevation,
|
||||
shape: widget.shape,
|
||||
clipBehavior: widget.clipBehavior,
|
||||
enableDrag: widget.enableDrag,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -346,10 +350,12 @@ class _ModalBottomSheetRoute<T> extends PopupRoute<T> {
|
|||
this.clipBehavior,
|
||||
this.modalBarrierColor,
|
||||
this.isDismissible = true,
|
||||
this.enableDrag = true,
|
||||
@required this.isScrollControlled,
|
||||
RouteSettings settings,
|
||||
}) : assert(isScrollControlled != null),
|
||||
assert(isDismissible != null),
|
||||
assert(enableDrag != null),
|
||||
super(settings: settings);
|
||||
|
||||
final WidgetBuilder builder;
|
||||
|
@ -361,6 +367,7 @@ class _ModalBottomSheetRoute<T> extends PopupRoute<T> {
|
|||
final Clip clipBehavior;
|
||||
final Color modalBarrierColor;
|
||||
final bool isDismissible;
|
||||
final bool enableDrag;
|
||||
|
||||
@override
|
||||
Duration get transitionDuration => _bottomSheetDuration;
|
||||
|
@ -399,6 +406,7 @@ class _ModalBottomSheetRoute<T> extends PopupRoute<T> {
|
|||
shape: shape,
|
||||
clipBehavior: clipBehavior,
|
||||
isScrollControlled: isScrollControlled,
|
||||
enableDrag: enableDrag,
|
||||
),
|
||||
);
|
||||
if (theme != null)
|
||||
|
@ -437,6 +445,9 @@ class _ModalBottomSheetRoute<T> extends PopupRoute<T> {
|
|||
/// The [isDismissible] parameter specifies whether the bottom sheet will be
|
||||
/// dismissed when user taps on the scrim.
|
||||
///
|
||||
/// The [enableDrag] parameter specifies whether the bottom sheet can be
|
||||
/// dragged up and down and dismissed by swiping downards.
|
||||
///
|
||||
/// The optional [backgroundColor], [elevation], [shape], and [clipBehavior]
|
||||
/// parameters can be passed in to customize the appearance and behavior of
|
||||
/// modal bottom sheets.
|
||||
|
@ -507,12 +518,14 @@ Future<T> showModalBottomSheet<T>({
|
|||
bool isScrollControlled = false,
|
||||
bool useRootNavigator = false,
|
||||
bool isDismissible = true,
|
||||
bool enableDrag = true,
|
||||
}) {
|
||||
assert(context != null);
|
||||
assert(builder != null);
|
||||
assert(isScrollControlled != null);
|
||||
assert(useRootNavigator != null);
|
||||
assert(isDismissible != null);
|
||||
assert(enableDrag != null);
|
||||
assert(debugCheckHasMediaQuery(context));
|
||||
assert(debugCheckHasMaterialLocalizations(context));
|
||||
|
||||
|
@ -526,7 +539,8 @@ Future<T> showModalBottomSheet<T>({
|
|||
shape: shape,
|
||||
clipBehavior: clipBehavior,
|
||||
isDismissible: isDismissible,
|
||||
modalBarrierColor: barrierColor
|
||||
modalBarrierColor: barrierColor,
|
||||
enableDrag: enableDrag,
|
||||
));
|
||||
}
|
||||
|
||||
|
|
|
@ -152,6 +152,113 @@ void main() {
|
|||
expect(find.text('BottomSheet'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('Swiping down a modal BottomSheet should dismiss it by default', (WidgetTester tester) async {
|
||||
BuildContext savedContext;
|
||||
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Builder(
|
||||
builder: (BuildContext context) {
|
||||
savedContext = context;
|
||||
return Container();
|
||||
},
|
||||
),
|
||||
));
|
||||
|
||||
await tester.pump();
|
||||
expect(find.text('BottomSheet'), findsNothing);
|
||||
|
||||
bool showBottomSheetThenCalled = false;
|
||||
showModalBottomSheet<void>(
|
||||
context: savedContext,
|
||||
isDismissible: false,
|
||||
builder: (BuildContext context) => const Text('BottomSheet'),
|
||||
).then<void>((void value) {
|
||||
showBottomSheetThenCalled = true;
|
||||
});
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('BottomSheet'), findsOneWidget);
|
||||
expect(showBottomSheetThenCalled, isFalse);
|
||||
|
||||
// Swipe the bottom sheet to dismiss it.
|
||||
await tester.drag(find.text('BottomSheet'), const Offset(0.0, 150.0));
|
||||
await tester.pumpAndSettle(); // Bottom sheet dismiss animation.
|
||||
expect(showBottomSheetThenCalled, isTrue);
|
||||
expect(find.text('BottomSheet'), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('Swiping down a modal BottomSheet should not dismiss it when enableDrag is false', (WidgetTester tester) async {
|
||||
BuildContext savedContext;
|
||||
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Builder(
|
||||
builder: (BuildContext context) {
|
||||
savedContext = context;
|
||||
return Container();
|
||||
},
|
||||
),
|
||||
));
|
||||
|
||||
await tester.pump();
|
||||
expect(find.text('BottomSheet'), findsNothing);
|
||||
|
||||
bool showBottomSheetThenCalled = false;
|
||||
showModalBottomSheet<void>(
|
||||
context: savedContext,
|
||||
isDismissible: false,
|
||||
enableDrag: false,
|
||||
builder: (BuildContext context) => const Text('BottomSheet'),
|
||||
).then<void>((void value) {
|
||||
showBottomSheetThenCalled = true;
|
||||
});
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('BottomSheet'), findsOneWidget);
|
||||
expect(showBottomSheetThenCalled, isFalse);
|
||||
|
||||
// Swipe the bottom sheet, attempting to dismiss it.
|
||||
await tester.drag(find.text('BottomSheet'), const Offset(0.0, 150.0));
|
||||
await tester.pumpAndSettle(); // Bottom sheet should not dismiss.
|
||||
expect(showBottomSheetThenCalled, isFalse);
|
||||
expect(find.text('BottomSheet'), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets('Swiping down a modal BottomSheet should dismiss it when enableDrag is true', (WidgetTester tester) async {
|
||||
BuildContext savedContext;
|
||||
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Builder(
|
||||
builder: (BuildContext context) {
|
||||
savedContext = context;
|
||||
return Container();
|
||||
},
|
||||
),
|
||||
));
|
||||
|
||||
await tester.pump();
|
||||
expect(find.text('BottomSheet'), findsNothing);
|
||||
|
||||
bool showBottomSheetThenCalled = false;
|
||||
showModalBottomSheet<void>(
|
||||
context: savedContext,
|
||||
isDismissible: false,
|
||||
enableDrag: true,
|
||||
builder: (BuildContext context) => const Text('BottomSheet'),
|
||||
).then<void>((void value) {
|
||||
showBottomSheetThenCalled = true;
|
||||
});
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('BottomSheet'), findsOneWidget);
|
||||
expect(showBottomSheetThenCalled, isFalse);
|
||||
|
||||
// Swipe the bottom sheet to dismiss it.
|
||||
await tester.drag(find.text('BottomSheet'), const Offset(0.0, 150.0));
|
||||
await tester.pumpAndSettle(); // Bottom sheet dismiss animation.
|
||||
expect(showBottomSheetThenCalled, isTrue);
|
||||
expect(find.text('BottomSheet'), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('Verify that a downwards fling dismisses a persistent BottomSheet', (WidgetTester tester) async {
|
||||
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
bool showBottomSheetThenCalled = false;
|
||||
|
|
Loading…
Reference in a new issue