Commit d17e80ce authored by Matt Perry's avatar Matt Perry Committed by GitHub

Fix bug with back gesture with a persistent bottom sheet showing. (#6498)

Fixes https://github.com/flutter/flutter/issues/6451
parent d4c2481e
...@@ -131,7 +131,7 @@ class _CupertinoBackGestureController extends NavigationGestureController { ...@@ -131,7 +131,7 @@ class _CupertinoBackGestureController extends NavigationGestureController {
} }
@override @override
void dragEnd(double velocity) { bool dragEnd(double velocity) {
if (velocity.abs() >= _kMinFlingVelocity) { if (velocity.abs() >= _kMinFlingVelocity) {
controller.fling(velocity: -velocity); controller.fling(velocity: -velocity);
} else if (controller.value <= 0.5) { } else if (controller.value <= 0.5) {
...@@ -141,8 +141,11 @@ class _CupertinoBackGestureController extends NavigationGestureController { ...@@ -141,8 +141,11 @@ class _CupertinoBackGestureController extends NavigationGestureController {
} }
// Don't end the gesture until the transition completes. // Don't end the gesture until the transition completes.
final AnimationStatus status = controller.status;
handleStatusChanged(controller.status); handleStatusChanged(controller.status);
controller?.addStatusListener(handleStatusChanged); controller?.addStatusListener(handleStatusChanged);
return (status == AnimationStatus.reverse || status == AnimationStatus.dismissed);
} }
void handleStatusChanged(AnimationStatus status) { void handleStatusChanged(AnimationStatus status) {
......
...@@ -820,12 +820,16 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin { ...@@ -820,12 +820,16 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin {
} }
void _handleDragEnd(DragEndDetails details) { void _handleDragEnd(DragEndDetails details) {
_backGestureController?.dragEnd(details.velocity.pixelsPerSecond.dx / context.size.width); final bool willPop = _backGestureController?.dragEnd(details.velocity.pixelsPerSecond.dx / context.size.width) ?? false;
if (willPop)
_currentBottomSheet?.close();
_backGestureController = null; _backGestureController = null;
} }
void _handleDragCancel() { void _handleDragCancel() {
_backGestureController?.dragEnd(0.0); final bool willPop = _backGestureController?.dragEnd(0.0) ?? false;
if (willPop)
_currentBottomSheet?.close();
_backGestureController = null; _backGestureController = null;
} }
......
...@@ -218,7 +218,10 @@ abstract class NavigationGestureController { ...@@ -218,7 +218,10 @@ abstract class NavigationGestureController {
/// The drag gesture has ended with a horizontal motion of /// The drag gesture has ended with a horizontal motion of
/// [fractionalVelocity] as a fraction of screen width per second. /// [fractionalVelocity] as a fraction of screen width per second.
void dragEnd(double fractionalVelocity); ///
/// Returns true if the gesture will complete (i.e. a back gesture will
/// result in a pop).
bool dragEnd(double fractionalVelocity);
} }
/// Signature for the [Navigator.popUntil] predicate argument. /// Signature for the [Navigator.popUntil] predicate argument.
......
...@@ -13,6 +13,38 @@ class TestOverlayRoute extends OverlayRoute<Null> { ...@@ -13,6 +13,38 @@ class TestOverlayRoute extends OverlayRoute<Null> {
Widget _build(BuildContext context) => new Text('Overlay'); Widget _build(BuildContext context) => new Text('Overlay');
} }
class PersistentBottomSheetTest extends StatefulWidget {
PersistentBottomSheetTest({ Key key }) : super(key: key);
@override
PersistentBottomSheetTestState createState() => new PersistentBottomSheetTestState();
}
class PersistentBottomSheetTestState extends State<PersistentBottomSheetTest> {
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
bool setStateCalled = false;
void showBottomSheet() {
_scaffoldKey.currentState.showBottomSheet/*<Null>*/((BuildContext context) {
return new Text('bottomSheet');
})
.closed.then((_) {
setState(() {
setStateCalled = true;
});
});
}
@override
Widget build(BuildContext context) {
return new Scaffold(
key: _scaffoldKey,
body: new Text('Sheet')
);
}
}
void main() { void main() {
testWidgets('Check onstage/offstage handling around transitions', (WidgetTester tester) async { testWidgets('Check onstage/offstage handling around transitions', (WidgetTester tester) async {
GlobalKey containerKey1 = new GlobalKey(); GlobalKey containerKey1 = new GlobalKey();
...@@ -332,4 +364,46 @@ void main() { ...@@ -332,4 +364,46 @@ void main() {
expect(find.text('Home'), isOnstage); expect(find.text('Home'), isOnstage);
expect(find.text('Settings'), findsNothing); expect(find.text('Settings'), findsNothing);
}); });
// Tests bug https://github.com/flutter/flutter/issues/6451
testWidgets('Check back gesture with a persistent bottom sheet showing', (WidgetTester tester) async {
GlobalKey containerKey1 = new GlobalKey();
GlobalKey containerKey2 = new GlobalKey();
final Map<String, WidgetBuilder> routes = <String, WidgetBuilder>{
'/': (_) => new Scaffold(key: containerKey1, body: new Text('Home')),
'/sheet': (_) => new PersistentBottomSheetTest(key: containerKey2),
};
await tester.pumpWidget(new MaterialApp(
routes: routes,
theme: new ThemeData(platform: TargetPlatform.iOS),
));
Navigator.pushNamed(containerKey1.currentContext, '/sheet');
await tester.pump();
await tester.pump(const Duration(seconds: 1));
expect(find.text('Home'), findsNothing);
expect(find.text('Sheet'), isOnstage);
// Show the bottom sheet.
PersistentBottomSheetTestState sheet = containerKey2.currentState;
sheet.showBottomSheet();
await tester.pump(const Duration(seconds: 1));
// Drag from left edge to invoke the gesture.
TestGesture gesture = await tester.startGesture(new Point(5.0, 100.0));
await gesture.moveBy(new Offset(500.0, 0.0));
await gesture.up();
await tester.pump();
await tester.pump(const Duration(seconds: 1));
expect(find.text('Home'), isOnstage);
expect(find.text('Sheet'), findsNothing);
// Sheet called setState and didn't crash.
expect(sheet.setStateCalled, isTrue);
});
} }
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