Unverified Commit 0f0cc449 authored by Hans Muller's avatar Hans Muller Committed by GitHub

Scaffold bottomSheet parameter: persistent, not a route (#18379)

parent aecb7d96
......@@ -24,7 +24,8 @@ const double _kCloseProgressThreshold = 0.5;
/// supplements the primary content of the app. A persistent bottom sheet
/// remains visible even when the user interacts with other parts of the app.
/// Persistent bottom sheets can be created and displayed with the
/// [ScaffoldState.showBottomSheet] function.
/// [ScaffoldState.showBottomSheet] function or by specifying the
/// [Scaffold.bottomSheet] constructor parameter.
///
/// * _Modal_. A modal bottom sheet is an alternative to a menu or a dialog and
/// prevents the user from interacting with the rest of the app. Modal bottom
......@@ -32,8 +33,8 @@ const double _kCloseProgressThreshold = 0.5;
/// function.
///
/// The [BottomSheet] widget itself is rarely used directly. Instead, prefer to
/// create a persistent bottom sheet with [ScaffoldState.showBottomSheet] and a modal
/// bottom sheet with [showModalBottomSheet].
/// create a persistent bottom sheet with [ScaffoldState.showBottomSheet] or
/// [Scaffold.bottomSheet], and a modal bottom sheet with [showModalBottomSheet].
///
/// See also:
///
......@@ -49,9 +50,11 @@ class BottomSheet extends StatefulWidget {
const BottomSheet({
Key key,
this.animationController,
this.enableDrag = true,
@required this.onClosing,
@required this.builder
}) : assert(onClosing != null),
}) : assert(enableDrag != null),
assert(onClosing != null),
assert(builder != null),
super(key: key);
......@@ -74,6 +77,12 @@ class BottomSheet extends StatefulWidget {
/// [Material] widget.
final WidgetBuilder builder;
/// If true, the bottom sheet can dragged up and down and dismissed by swiping
/// downards.
///
/// Default is true.
final bool enableDrag;
@override
_BottomSheetState createState() => new _BottomSheetState();
......@@ -124,13 +133,14 @@ class _BottomSheetState extends State<BottomSheet> {
@override
Widget build(BuildContext context) {
return new GestureDetector(
final Widget bottomSheet = new Material(
key: _childKey,
child: widget.builder(context),
);
return !widget.enableDrag ? bottomSheet : new GestureDetector(
onVerticalDragUpdate: _handleDragUpdate,
onVerticalDragEnd: _handleDragEnd,
child: new Material(
key: _childKey,
child: widget.builder(context)
)
child: bottomSheet,
);
}
}
......@@ -289,24 +299,30 @@ Future<T> showModalBottomSheet<T>({
/// Shows a persistent material design bottom sheet in the nearest [Scaffold].
///
/// Returns a controller that can be used to close and otherwise manipulate the
/// bottom sheet.
///
/// To rebuild the bottom sheet (e.g. if it is stateful), call
/// [PersistentBottomSheetController.setState] on the controller returned by
/// this method.
///
/// The new bottom sheet becomes a [LocalHistoryEntry] for the enclosing
/// [ModalRoute] and a back button is added to the appbar of the [Scaffold]
/// that closes the bottom sheet.
///
/// To create a persistent bottom sheet that is not a [LocalHistoryEntry] and
/// does not add a back button to the enclosing Scaffold's appbar, use the
/// [Scaffold.bottomSheet] constructor parameter.
///
/// A persistent bottom sheet shows information that supplements the primary
/// content of the app. A persistent bottom sheet remains visible even when the
/// user interacts with other parts of the app. A [Scaffold] is required in the
/// given `context`; its [ScaffoldState.showBottomSheet] method is used to
/// actually show the bottom sheet.
/// content of the app. A persistent bottom sheet remains visible even when
/// the user interacts with other parts of the app.
///
/// A closely related widget is a modal bottom sheet, which is an alternative
/// to a menu or a dialog and prevents the user from interacting with the rest
/// of the app. Modal bottom sheets can be created and displayed with the
/// [showModalBottomSheet] function.
///
/// Returns a controller that can be used to close and otherwise manipulate the
/// bottom sheet.
///
/// To rebuild the bottom sheet (e.g. if it is stateful), call
/// [PersistentBottomSheetController.setState] on the value returned from this
/// method.
///
/// The `context` argument is used to look up the [Scaffold] for the bottom
/// sheet. It is only used when the method is called. Its corresponding widget
/// can be safely removed from the tree before the bottom sheet is closed.
......
......@@ -133,4 +133,62 @@ void main() {
),
);
});
testWidgets('Scaffold.bottomSheet', (WidgetTester tester) async {
final Key bottomSheetKey = new UniqueKey();
await tester.pumpWidget(
new MaterialApp(
home: new Scaffold(
body: const Placeholder(),
bottomSheet: new Container(
key: bottomSheetKey,
alignment: Alignment.center,
height: 200.0,
child: new Builder(
builder: (BuildContext context) {
return new RaisedButton(
child: const Text('showModalBottomSheet'),
onPressed: () {
showModalBottomSheet<void>(
context: context,
builder: (BuildContext context) => const Text('modal bottom sheet'),
);
},
);
},
),
),
),
),
);
expect(find.text('showModalBottomSheet'), findsOneWidget);
expect(tester.getSize(find.byKey(bottomSheetKey)), const Size(800.0, 200.0));
expect(tester.getTopLeft(find.byKey(bottomSheetKey)), const Offset(0.0, 400.0));
// Show the modal bottomSheet
await tester.tap(find.text('showModalBottomSheet'));
await tester.pumpAndSettle();
expect(find.text('modal bottom sheet'), findsOneWidget);
// Dismiss the modal bottomSheet
await tester.tap(find.text('modal bottom sheet'));
await tester.pumpAndSettle();
expect(find.text('modal bottom sheet'), findsNothing);
expect(find.text('showModalBottomSheet'), findsOneWidget);
// Remove the persistent bottomSheet
await tester.pumpWidget(
new MaterialApp(
home: const Scaffold(
bottomSheet: null,
body: const Placeholder(),
),
),
);
await tester.pumpAndSettle();
expect(find.text('showModalBottomSheet'), findsNothing);
expect(find.byKey(bottomSheetKey), findsNothing);
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment