mirror of
https://github.com/flutter/flutter
synced 2024-10-13 19:52:53 +00:00
Add parameter to Scaffold so its possible to disable open Drawer drag gesture (#50925)
This commit is contained in:
parent
9295b34850
commit
74e564da2d
|
@ -232,6 +232,7 @@ class DrawerController extends StatefulWidget {
|
|||
this.dragStartBehavior = DragStartBehavior.start,
|
||||
this.scrimColor,
|
||||
this.edgeDragWidth,
|
||||
this.enableOpenDragGesture = true,
|
||||
}) : assert(child != null),
|
||||
assert(dragStartBehavior != null),
|
||||
assert(alignment != null),
|
||||
|
@ -278,6 +279,11 @@ class DrawerController extends StatefulWidget {
|
|||
/// By default, the color used is [Colors.black54]
|
||||
final Color scrimColor;
|
||||
|
||||
/// Determines if the [Drawer] can be opened with a drag gesture.
|
||||
///
|
||||
/// By default, the drag gesture is enabled.
|
||||
final bool enableOpenDragGesture;
|
||||
|
||||
/// The width of the area within which a horizontal swipe will open the
|
||||
/// drawer.
|
||||
///
|
||||
|
@ -505,18 +511,22 @@ class DrawerControllerState extends State<DrawerController> with SingleTickerPro
|
|||
}
|
||||
|
||||
if (_controller.status == AnimationStatus.dismissed) {
|
||||
return Align(
|
||||
alignment: _drawerOuterAlignment,
|
||||
child: GestureDetector(
|
||||
key: _gestureDetectorKey,
|
||||
onHorizontalDragUpdate: _move,
|
||||
onHorizontalDragEnd: _settle,
|
||||
behavior: HitTestBehavior.translucent,
|
||||
excludeFromSemantics: true,
|
||||
dragStartBehavior: widget.dragStartBehavior,
|
||||
child: Container(width: dragAreaWidth),
|
||||
),
|
||||
);
|
||||
if (widget.enableOpenDragGesture) {
|
||||
return Align(
|
||||
alignment: _drawerOuterAlignment,
|
||||
child: GestureDetector(
|
||||
key: _gestureDetectorKey,
|
||||
onHorizontalDragUpdate: _move,
|
||||
onHorizontalDragEnd: _settle,
|
||||
behavior: HitTestBehavior.translucent,
|
||||
excludeFromSemantics: true,
|
||||
dragStartBehavior: widget.dragStartBehavior,
|
||||
child: Container(width: dragAreaWidth),
|
||||
),
|
||||
);
|
||||
} else {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
} else {
|
||||
bool platformHasBackButton;
|
||||
switch (Theme.of(context).platform) {
|
||||
|
|
|
@ -1011,6 +1011,8 @@ class Scaffold extends StatefulWidget {
|
|||
this.extendBodyBehindAppBar = false,
|
||||
this.drawerScrimColor,
|
||||
this.drawerEdgeDragWidth,
|
||||
this.drawerEnableOpenDragGesture = true,
|
||||
this.endDrawerEnableOpenDragGesture = true,
|
||||
}) : assert(primary != null),
|
||||
assert(extendBody != null),
|
||||
assert(extendBodyBehindAppBar != null),
|
||||
|
@ -1113,9 +1115,10 @@ class Scaffold extends StatefulWidget {
|
|||
/// To close the drawer, use [Navigator.pop].
|
||||
///
|
||||
/// {@tool dartpad --template=stateful_widget_material}
|
||||
/// To disable the drawer edge swipe, set the [Scaffold.drawerEdgeWidth] to 0.
|
||||
/// Then, use [ScaffoldState.openDrawer] to open the drawer and
|
||||
/// [Navigator.pop] to close it.
|
||||
/// To disable the drawer edge swipe, set the
|
||||
/// [Scaffold.drawerEnableOpenDragGesture] to false. Then, use
|
||||
/// [ScaffoldState.openDrawer] to open the drawer and [Navigator.pop] to close
|
||||
/// it.
|
||||
///
|
||||
/// ```dart
|
||||
/// final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
|
@ -1153,7 +1156,8 @@ class Scaffold extends StatefulWidget {
|
|||
/// ),
|
||||
/// ),
|
||||
/// ),
|
||||
/// drawerEdgeDragWidth: 0.0, // Disable opening the drawer with a swipe gesture.
|
||||
/// // Disable opening the drawer with a swipe gesture.
|
||||
/// drawerEnableOpenDragGesture: false,
|
||||
/// );
|
||||
/// }
|
||||
/// ```
|
||||
|
@ -1171,9 +1175,10 @@ class Scaffold extends StatefulWidget {
|
|||
/// To close the drawer, use [Navigator.pop].
|
||||
///
|
||||
/// {@tool dartpad --template=stateful_widget_material}
|
||||
/// To disable the drawer edge swipe, set the [Scaffold.drawerEdgeWidth]
|
||||
/// to 0. Then, use [ScaffoldState.openEndDrawer] to open the drawer and
|
||||
/// [Navigator.pop] to close it.
|
||||
/// To disable the drawer edge swipe, set the
|
||||
/// [Scaffold.endDrawerEnableOpenDragGesture] to false. Then, use
|
||||
/// [ScaffoldState.openEndDrawer] to open the drawer and [Navigator.pop] to
|
||||
/// close it.
|
||||
///
|
||||
/// ```dart
|
||||
/// final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>();
|
||||
|
@ -1211,7 +1216,8 @@ class Scaffold extends StatefulWidget {
|
|||
/// ),
|
||||
/// ),
|
||||
/// ),
|
||||
/// drawerEdgeDragWidth: 0.0, // Disable opening the drawer with a swipe gesture.
|
||||
/// // Disable opening the end drawer with a swipe gesture.
|
||||
/// endDrawerEnableOpenDragGesture: false,
|
||||
/// );
|
||||
/// }
|
||||
/// ```
|
||||
|
@ -1313,6 +1319,18 @@ class Scaffold extends StatefulWidget {
|
|||
/// 20.0 will be added to `MediaQuery.of(context).padding.left`.
|
||||
final double drawerEdgeDragWidth;
|
||||
|
||||
/// Determines if the [Scaffold.drawer] can be opened with a drag
|
||||
/// gesture.
|
||||
///
|
||||
/// By default, the drag gesture is enabled.
|
||||
final bool drawerEnableOpenDragGesture;
|
||||
|
||||
/// Determines if the [Scaffold.endDrawer] can be opened with a
|
||||
/// drag gesture.
|
||||
///
|
||||
/// By default, the drag gesture is enabled.
|
||||
final bool endDrawerEnableOpenDragGesture;
|
||||
|
||||
/// This flag is deprecated and fixes and issue with incorrect clipping
|
||||
/// and positioning of the [SnackBar] set to [SnackBarBehavior.floating].
|
||||
@Deprecated(
|
||||
|
@ -2230,6 +2248,7 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin {
|
|||
dragStartBehavior: widget.drawerDragStartBehavior,
|
||||
scrimColor: widget.drawerScrimColor,
|
||||
edgeDragWidth: widget.drawerEdgeDragWidth,
|
||||
enableOpenDragGesture: widget.endDrawerEnableOpenDragGesture,
|
||||
),
|
||||
_ScaffoldSlot.endDrawer,
|
||||
// remove the side padding from the side we're not touching
|
||||
|
@ -2254,6 +2273,7 @@ class ScaffoldState extends State<Scaffold> with TickerProviderStateMixin {
|
|||
dragStartBehavior: widget.drawerDragStartBehavior,
|
||||
scrimColor: widget.drawerScrimColor,
|
||||
edgeDragWidth: widget.drawerEdgeDragWidth,
|
||||
enableOpenDragGesture: widget.drawerEnableOpenDragGesture,
|
||||
),
|
||||
_ScaffoldSlot.drawer,
|
||||
// remove the side padding from the side we're not touching
|
||||
|
|
|
@ -1596,6 +1596,142 @@ void main() {
|
|||
expect(scaffoldState.isDrawerOpen, true);
|
||||
});
|
||||
|
||||
testWidgets('Drawer does not open with a drag gesture when it is disabled', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Scaffold(
|
||||
drawer: const Drawer(
|
||||
child: Text('Drawer'),
|
||||
),
|
||||
drawerEnableOpenDragGesture: true,
|
||||
body: const Text('Scaffold Body'),
|
||||
appBar: AppBar(
|
||||
centerTitle: true,
|
||||
title: const Text('Title'),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
ScaffoldState scaffoldState = tester.state(find.byType(Scaffold));
|
||||
expect(scaffoldState.isDrawerOpen, false);
|
||||
|
||||
// Test that we can open the drawer with a drag gesture when
|
||||
// `Scaffold.drawerEnableDragGesture` is true.
|
||||
await tester.dragFrom(const Offset(0, 100), const Offset(300, 0));
|
||||
await tester.pumpAndSettle();
|
||||
expect(scaffoldState.isDrawerOpen, true);
|
||||
|
||||
await tester.dragFrom(const Offset(300, 100), const Offset(-300, 0));
|
||||
await tester.pumpAndSettle();
|
||||
expect(scaffoldState.isDrawerOpen, false);
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Scaffold(
|
||||
drawer: const Drawer(
|
||||
child: Text('Drawer'),
|
||||
),
|
||||
drawerEnableOpenDragGesture: false,
|
||||
body: const Text('Scaffold body'),
|
||||
appBar: AppBar(
|
||||
centerTitle: true,
|
||||
title: const Text('Title'),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
scaffoldState = tester.state(find.byType(Scaffold));
|
||||
expect(scaffoldState.isDrawerOpen, false);
|
||||
|
||||
// Test that we cannot open the drawer with a drag gesture when
|
||||
// `Scaffold.drawerEnableDragGesture` is false.
|
||||
await tester.dragFrom(const Offset(0, 100), const Offset(300, 0));
|
||||
await tester.pumpAndSettle();
|
||||
expect(scaffoldState.isDrawerOpen, false);
|
||||
|
||||
// Test that we can close drawer with a drag gesture when
|
||||
// `Scaffold.drawerEnableDragGesture` is false.
|
||||
final Finder drawerOpenButton = find.byType(IconButton).first;
|
||||
await tester.tap(drawerOpenButton);
|
||||
await tester.pumpAndSettle();
|
||||
expect(scaffoldState.isDrawerOpen, true);
|
||||
|
||||
await tester.dragFrom(const Offset(300, 100), const Offset(-300, 0));
|
||||
await tester.pumpAndSettle();
|
||||
expect(scaffoldState.isDrawerOpen, false);
|
||||
});
|
||||
|
||||
testWidgets('End drawer does not open with a drag gesture when it is disabled', (WidgetTester tester) async {
|
||||
double screenWidth;
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Builder(
|
||||
builder: (BuildContext context) {
|
||||
screenWidth = MediaQuery.of(context).size.width;
|
||||
return Scaffold(
|
||||
endDrawer: const Drawer(
|
||||
child: Text('Drawer'),
|
||||
),
|
||||
endDrawerEnableOpenDragGesture: true,
|
||||
body: const Text('Scaffold Body'),
|
||||
appBar: AppBar(
|
||||
centerTitle: true,
|
||||
title: const Text('Title'),
|
||||
),
|
||||
);
|
||||
}
|
||||
),
|
||||
),
|
||||
);
|
||||
ScaffoldState scaffoldState = tester.state(find.byType(Scaffold));
|
||||
expect(scaffoldState.isEndDrawerOpen, false);
|
||||
|
||||
// Test that we can open the end drawer with a drag gesture when
|
||||
// `Scaffold.endDrawerEnableDragGesture` is true.
|
||||
await tester.dragFrom(Offset(screenWidth - 1, 100), const Offset(-300, 0));
|
||||
await tester.pumpAndSettle();
|
||||
expect(scaffoldState.isEndDrawerOpen, true);
|
||||
|
||||
await tester.dragFrom(Offset(screenWidth - 300, 100), const Offset(300, 0));
|
||||
await tester.pumpAndSettle();
|
||||
expect(scaffoldState.isEndDrawerOpen, false);
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Scaffold(
|
||||
endDrawer: const Drawer(
|
||||
child: Text('Drawer'),
|
||||
),
|
||||
endDrawerEnableOpenDragGesture: false,
|
||||
body: const Text('Scaffold body'),
|
||||
appBar: AppBar(
|
||||
centerTitle: true,
|
||||
title: const Text('Title'),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
scaffoldState = tester.state(find.byType(Scaffold));
|
||||
expect(scaffoldState.isEndDrawerOpen, false);
|
||||
|
||||
// Test that we cannot open the end drawer with a drag gesture when
|
||||
// `Scaffold.endDrawerEnableDragGesture` is false.
|
||||
await tester.dragFrom(Offset(screenWidth - 1, 100), const Offset(-300, 0));
|
||||
await tester.pumpAndSettle();
|
||||
expect(scaffoldState.isEndDrawerOpen, false);
|
||||
|
||||
// Test that we can close the end drawer a with drag gesture when
|
||||
// `Scaffold.endDrawerEnableDragGesture` is false.
|
||||
final Finder endDrawerOpenButton = find.byType(IconButton).first;
|
||||
await tester.tap(endDrawerOpenButton);
|
||||
await tester.pumpAndSettle();
|
||||
expect(scaffoldState.isEndDrawerOpen, true);
|
||||
|
||||
await tester.dragFrom(Offset(screenWidth - 300, 100), const Offset(300, 0));
|
||||
await tester.pumpAndSettle();
|
||||
expect(scaffoldState.isEndDrawerOpen, false);
|
||||
});
|
||||
|
||||
testWidgets('Nested scaffold body insets', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/20295
|
||||
final Key bodyKey = UniqueKey();
|
||||
|
|
Loading…
Reference in a new issue