Commit 310a9819 authored by Hans Muller's avatar Hans Muller Committed by GitHub

Handle dragging a bottom sheet past the bottom (#5541)

parent 81d67268
...@@ -108,10 +108,12 @@ class _BottomSheetState extends State<BottomSheet> { ...@@ -108,10 +108,12 @@ class _BottomSheetState extends State<BottomSheet> {
return; return;
if (details.velocity.pixelsPerSecond.dy > _kMinFlingVelocity) { if (details.velocity.pixelsPerSecond.dy > _kMinFlingVelocity) {
double flingVelocity = -details.velocity.pixelsPerSecond.dy / _childHeight; double flingVelocity = -details.velocity.pixelsPerSecond.dy / _childHeight;
if (config.animationController.value > 0.0)
config.animationController.fling(velocity: flingVelocity); config.animationController.fling(velocity: flingVelocity);
if (flingVelocity < 0.0) if (flingVelocity < 0.0)
config.onClosing(); config.onClosing();
} else if (config.animationController.value < _kCloseProgressThreshold) { } else if (config.animationController.value < _kCloseProgressThreshold) {
if (config.animationController.value > 0.0)
config.animationController.fling(velocity: -1.0); config.animationController.fling(velocity: -1.0);
config.onClosing(); config.onClosing();
} else { } else {
......
...@@ -454,7 +454,7 @@ class ScaffoldState extends State<Scaffold> { ...@@ -454,7 +454,7 @@ class ScaffoldState extends State<Scaffold> {
// PERSISTENT BOTTOM SHEET API // PERSISTENT BOTTOM SHEET API
List<Widget> _dismissedBottomSheets; final List<Widget> _dismissedBottomSheets = <Widget>[];
PersistentBottomSheetController<dynamic> _currentBottomSheet; PersistentBottomSheetController<dynamic> _currentBottomSheet;
/// Shows a persistent material design bottom sheet. /// Shows a persistent material design bottom sheet.
...@@ -491,9 +491,11 @@ class ScaffoldState extends State<Scaffold> { ...@@ -491,9 +491,11 @@ class ScaffoldState extends State<Scaffold> {
assert(_currentBottomSheet._widget == bottomSheet); assert(_currentBottomSheet._widget == bottomSheet);
assert(bottomSheetKey.currentState != null); assert(bottomSheetKey.currentState != null);
bottomSheetKey.currentState.close(); bottomSheetKey.currentState.close();
_dismissedBottomSheets ??= <Widget>[]; if (controller.status != AnimationStatus.dismissed)
_dismissedBottomSheets.add(bottomSheet); _dismissedBottomSheets.add(bottomSheet);
setState(() {
_currentBottomSheet = null; _currentBottomSheet = null;
});
completer.complete(); completer.complete();
} }
); );
...@@ -505,10 +507,11 @@ class ScaffoldState extends State<Scaffold> { ...@@ -505,10 +507,11 @@ class ScaffoldState extends State<Scaffold> {
entry.remove(); entry.remove();
}, },
onDismissed: () { onDismissed: () {
assert(_dismissedBottomSheets != null); if (_dismissedBottomSheets.contains(bottomSheet)) {
setState(() { setState(() {
_dismissedBottomSheets.remove(bottomSheet); _dismissedBottomSheets.remove(bottomSheet);
}); });
}
}, },
builder: builder builder: builder
); );
...@@ -728,10 +731,9 @@ class ScaffoldState extends State<Scaffold> { ...@@ -728,10 +731,9 @@ class ScaffoldState extends State<Scaffold> {
} }
// Otherwise the AppBar will be part of a [app bar, body] Stack. See AppBarBehavior.scroll below. // Otherwise the AppBar will be part of a [app bar, body] Stack. See AppBarBehavior.scroll below.
if (_currentBottomSheet != null || if (_currentBottomSheet != null || _dismissedBottomSheets.isNotEmpty) {
(_dismissedBottomSheets != null && _dismissedBottomSheets.isNotEmpty)) {
final List<Widget> bottomSheets = <Widget>[]; final List<Widget> bottomSheets = <Widget>[];
if (_dismissedBottomSheets != null && _dismissedBottomSheets.isNotEmpty) if (_dismissedBottomSheets.isNotEmpty)
bottomSheets.addAll(_dismissedBottomSheets); bottomSheets.addAll(_dismissedBottomSheets);
if (_currentBottomSheet != null) if (_currentBottomSheet != null)
bottomSheets.add(_currentBottomSheet._widget); bottomSheets.add(_currentBottomSheet._widget);
......
...@@ -110,4 +110,33 @@ void main() { ...@@ -110,4 +110,33 @@ void main() {
expect(find.text('BottomSheet'), findsNothing); expect(find.text('BottomSheet'), findsNothing);
}); });
testWidgets('Verify that dragging past the bottom dismisses a persistent BottomSheet', (WidgetTester tester) async {
// This is a regression test for https://github.com/flutter/flutter/issues/5528
GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey<ScaffoldState>();
await tester.pumpWidget(new MaterialApp(
home: new Scaffold(
key: scaffoldKey,
body: new Center(child: new Text('body'))
)
));
scaffoldKey.currentState.showBottomSheet((BuildContext context) {
return new Container(
margin: new EdgeInsets.all(40.0),
child: new Text('BottomSheet')
);
});
await tester.pump(); // bottom sheet show animation starts
await tester.pump(new Duration(seconds: 1)); // animation done
expect(find.text('BottomSheet'), findsOneWidget);
await tester.fling(find.text('BottomSheet'), const Offset(0.0, 400.0), 1000.0);
await tester.pump(); // drain the microtask queue (Future completion callback)
await tester.pump(); // bottom sheet dismiss animation starts
await tester.pump(new Duration(seconds: 1)); // animation done
expect(find.text('BottomSheet'), 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