mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Expose enableDrag property for showBottomSheet (#90932)
This commit is contained in:
parent
3f688f6e83
commit
8733218305
@ -722,6 +722,9 @@ Future<T?> showModalBottomSheet<T>({
|
||||
/// persistent bottom sheets (see the documentation for these on [BottomSheet]
|
||||
/// for more details).
|
||||
///
|
||||
/// The [enableDrag] parameter specifies whether the bottom sheet can be
|
||||
/// dragged up and down and dismissed by swiping downwards.
|
||||
///
|
||||
/// To rebuild the bottom sheet (e.g. if it is stateful), call
|
||||
/// [PersistentBottomSheetController.setState] on the controller returned by
|
||||
/// this method.
|
||||
@ -759,6 +762,7 @@ PersistentBottomSheetController<T> showBottomSheet<T>({
|
||||
ShapeBorder? shape,
|
||||
Clip? clipBehavior,
|
||||
BoxConstraints? constraints,
|
||||
bool? enableDrag,
|
||||
AnimationController? transitionAnimationController,
|
||||
}) {
|
||||
assert(context != null);
|
||||
@ -772,6 +776,7 @@ PersistentBottomSheetController<T> showBottomSheet<T>({
|
||||
shape: shape,
|
||||
clipBehavior: clipBehavior,
|
||||
constraints: constraints,
|
||||
enableDrag: enableDrag,
|
||||
transitionAnimationController: transitionAnimationController,
|
||||
);
|
||||
}
|
||||
|
||||
@ -2318,6 +2318,7 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin, Resto
|
||||
ShapeBorder? shape,
|
||||
Clip? clipBehavior,
|
||||
BoxConstraints? constraints,
|
||||
bool? enableDrag,
|
||||
bool shouldDisposeAnimationController = true,
|
||||
}) {
|
||||
assert(() {
|
||||
@ -2367,7 +2368,7 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin, Resto
|
||||
bottomSheet = _StandardBottomSheet(
|
||||
key: bottomSheetKey,
|
||||
animationController: animationController,
|
||||
enableDrag: !isPersistent,
|
||||
enableDrag: enableDrag ?? !isPersistent,
|
||||
onClosing: () {
|
||||
if (_currentBottomSheet == null) {
|
||||
return;
|
||||
@ -2468,6 +2469,7 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin, Resto
|
||||
ShapeBorder? shape,
|
||||
Clip? clipBehavior,
|
||||
BoxConstraints? constraints,
|
||||
bool? enableDrag,
|
||||
AnimationController? transitionAnimationController,
|
||||
}) {
|
||||
assert(() {
|
||||
@ -2494,6 +2496,7 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin, Resto
|
||||
shape: shape,
|
||||
clipBehavior: clipBehavior,
|
||||
constraints: constraints,
|
||||
enableDrag: enableDrag,
|
||||
shouldDisposeAnimationController: transitionAnimationController == null,
|
||||
);
|
||||
});
|
||||
|
||||
@ -88,6 +88,150 @@ void main() {
|
||||
await tester.pumpWidget(Container());
|
||||
});
|
||||
|
||||
|
||||
testWidgets('Swiping down a BottomSheet should dismiss it by default', (WidgetTester tester) async {
|
||||
|
||||
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
bool showBottomSheetThenCalled = false;
|
||||
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Scaffold(
|
||||
key: scaffoldKey,
|
||||
body: const Center(child: Text('body')),
|
||||
),
|
||||
));
|
||||
|
||||
await tester.pump();
|
||||
expect(showBottomSheetThenCalled, isFalse);
|
||||
expect(find.text('BottomSheet'), findsNothing);
|
||||
|
||||
scaffoldKey.currentState!.showBottomSheet<void>((BuildContext context) {
|
||||
return const SizedBox(
|
||||
height: 200.0,
|
||||
child: Text('BottomSheet'),
|
||||
);
|
||||
}).closed.whenComplete(() {
|
||||
showBottomSheetThenCalled = true;
|
||||
});
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
expect(showBottomSheetThenCalled, isFalse);
|
||||
expect(find.text('BottomSheet'), findsOneWidget);
|
||||
|
||||
// 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 BottomSheet should not dismiss it when enableDrag is false', (WidgetTester tester) async {
|
||||
|
||||
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
bool showBottomSheetThenCalled = false;
|
||||
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Scaffold(
|
||||
key: scaffoldKey,
|
||||
body: const Center(child: Text('body')),
|
||||
),
|
||||
));
|
||||
|
||||
await tester.pump();
|
||||
expect(showBottomSheetThenCalled, isFalse);
|
||||
expect(find.text('BottomSheet'), findsNothing);
|
||||
|
||||
scaffoldKey.currentState!.showBottomSheet<void>((BuildContext context) {
|
||||
return const SizedBox(
|
||||
height: 200.0,
|
||||
child: Text('BottomSheet'),
|
||||
);
|
||||
},
|
||||
enableDrag: false
|
||||
).closed.whenComplete(() {
|
||||
showBottomSheetThenCalled = true;
|
||||
});
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
expect(showBottomSheetThenCalled, isFalse);
|
||||
expect(find.text('BottomSheet'), findsOneWidget);
|
||||
|
||||
// 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 BottomSheet should dismiss it when enableDrag is true', (WidgetTester tester) async {
|
||||
final GlobalKey<ScaffoldState> scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
bool showBottomSheetThenCalled = false;
|
||||
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Scaffold(
|
||||
key: scaffoldKey,
|
||||
body: const Center(child: Text('body')),
|
||||
),
|
||||
));
|
||||
|
||||
await tester.pump();
|
||||
expect(showBottomSheetThenCalled, isFalse);
|
||||
expect(find.text('BottomSheet'), findsNothing);
|
||||
|
||||
scaffoldKey.currentState!.showBottomSheet<void>((BuildContext context) {
|
||||
return const SizedBox(
|
||||
height: 200.0,
|
||||
child: Text('BottomSheet'),
|
||||
);
|
||||
},
|
||||
enableDrag: true
|
||||
).closed.whenComplete(() {
|
||||
showBottomSheetThenCalled = true;
|
||||
});
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
expect(showBottomSheetThenCalled, isFalse);
|
||||
expect(find.text('BottomSheet'), findsOneWidget);
|
||||
|
||||
// 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('Modal BottomSheet builder should only be called once', (WidgetTester tester) async {
|
||||
late BuildContext savedContext;
|
||||
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Builder(
|
||||
builder: (BuildContext context) {
|
||||
savedContext = context;
|
||||
return Container();
|
||||
},
|
||||
),
|
||||
));
|
||||
|
||||
int numBuilderCalls = 0;
|
||||
showModalBottomSheet<void>(
|
||||
context: savedContext,
|
||||
isDismissible: false,
|
||||
enableDrag: true,
|
||||
builder: (BuildContext context) {
|
||||
numBuilderCalls++;
|
||||
return const Text('BottomSheet');
|
||||
},
|
||||
);
|
||||
|
||||
await tester.pumpAndSettle();
|
||||
expect(numBuilderCalls, 1);
|
||||
|
||||
// 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(numBuilderCalls, 1);
|
||||
});
|
||||
|
||||
testWidgets('Tapping on a modal BottomSheet should not dismiss it', (WidgetTester tester) async {
|
||||
late BuildContext savedContext;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user