mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00
Fix drawers are draggable on desktop platforms (#100476)
This commit is contained in:
parent
bd683066cb
commit
1718519188
@ -565,6 +565,19 @@ class DrawerControllerState extends State<DrawerController> with SingleTickerPro
|
||||
final bool drawerIsStart = widget.alignment == DrawerAlignment.start;
|
||||
final EdgeInsets padding = MediaQuery.of(context).padding;
|
||||
final TextDirection textDirection = Directionality.of(context);
|
||||
final bool isDesktop;
|
||||
switch (Theme.of(context).platform) {
|
||||
case TargetPlatform.android:
|
||||
case TargetPlatform.iOS:
|
||||
case TargetPlatform.fuchsia:
|
||||
isDesktop = false;
|
||||
break;
|
||||
case TargetPlatform.macOS:
|
||||
case TargetPlatform.linux:
|
||||
case TargetPlatform.windows:
|
||||
isDesktop = true;
|
||||
break;
|
||||
}
|
||||
|
||||
double? dragAreaWidth = widget.edgeDragWidth;
|
||||
if (widget.edgeDragWidth == null) {
|
||||
@ -581,7 +594,7 @@ class DrawerControllerState extends State<DrawerController> with SingleTickerPro
|
||||
}
|
||||
|
||||
if (_controller.status == AnimationStatus.dismissed) {
|
||||
if (widget.enableOpenDragGesture) {
|
||||
if (widget.enableOpenDragGesture && !isDesktop) {
|
||||
return Align(
|
||||
alignment: _drawerOuterAlignment,
|
||||
child: GestureDetector(
|
||||
@ -612,15 +625,8 @@ class DrawerControllerState extends State<DrawerController> with SingleTickerPro
|
||||
break;
|
||||
}
|
||||
assert(platformHasBackButton != null);
|
||||
return GestureDetector(
|
||||
key: _gestureDetectorKey,
|
||||
onHorizontalDragDown: _handleDragDown,
|
||||
onHorizontalDragUpdate: _move,
|
||||
onHorizontalDragEnd: _settle,
|
||||
onHorizontalDragCancel: _handleDragCancel,
|
||||
excludeFromSemantics: true,
|
||||
dragStartBehavior: widget.dragStartBehavior,
|
||||
child: RepaintBoundary(
|
||||
|
||||
final Widget child = RepaintBoundary(
|
||||
child: Stack(
|
||||
children: <Widget>[
|
||||
BlockSemantics(
|
||||
@ -631,7 +637,6 @@ class DrawerControllerState extends State<DrawerController> with SingleTickerPro
|
||||
onTap: close,
|
||||
child: Semantics(
|
||||
label: MaterialLocalizations.of(context).modalBarrierDismissLabel,
|
||||
child: MouseRegion(
|
||||
child: Container( // The drawer's "scrim"
|
||||
color: _scrimColorTween.evaluate(_controller),
|
||||
),
|
||||
@ -639,7 +644,6 @@ class DrawerControllerState extends State<DrawerController> with SingleTickerPro
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: _drawerOuterAlignment,
|
||||
child: Align(
|
||||
@ -656,7 +660,21 @@ class DrawerControllerState extends State<DrawerController> with SingleTickerPro
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
if (isDesktop) {
|
||||
return child;
|
||||
}
|
||||
|
||||
return GestureDetector(
|
||||
key: _gestureDetectorKey,
|
||||
onHorizontalDragDown: _handleDragDown,
|
||||
onHorizontalDragUpdate: _move,
|
||||
onHorizontalDragEnd: _settle,
|
||||
onHorizontalDragCancel: _handleDragCancel,
|
||||
excludeFromSemantics: true,
|
||||
dragStartBehavior: widget.dragStartBehavior,
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1617,7 +1617,7 @@ class Scaffold extends StatefulWidget {
|
||||
/// [Navigator.pop].
|
||||
///
|
||||
/// {@tool dartpad}
|
||||
/// To disable the drawer edge swipe, set the
|
||||
/// To disable the drawer edge swipe on mobile, set the
|
||||
/// [Scaffold.drawerEnableOpenDragGesture] to false. Then, use
|
||||
/// [ScaffoldState.openDrawer] to open the drawer and [Navigator.pop] to close
|
||||
/// it.
|
||||
@ -1739,15 +1739,19 @@ class Scaffold extends StatefulWidget {
|
||||
final double? drawerEdgeDragWidth;
|
||||
|
||||
/// Determines if the [Scaffold.drawer] can be opened with a drag
|
||||
/// gesture.
|
||||
/// gesture on mobile.
|
||||
///
|
||||
/// By default, the drag gesture is enabled.
|
||||
/// On desktop platforms, the drawer is not draggable.
|
||||
///
|
||||
/// By default, the drag gesture is enabled on mobile.
|
||||
final bool drawerEnableOpenDragGesture;
|
||||
|
||||
/// Determines if the [Scaffold.endDrawer] can be opened with a
|
||||
/// drag gesture.
|
||||
/// gesture on mobile.
|
||||
///
|
||||
/// By default, the drag gesture is enabled.
|
||||
/// On desktop platforms, the drawer is not draggable.
|
||||
///
|
||||
/// By default, the drag gesture is enabled on mobile.
|
||||
final bool endDrawerEnableOpenDragGesture;
|
||||
|
||||
/// Restoration ID to save and restore the state of the [Scaffold].
|
||||
|
@ -1777,7 +1777,7 @@ void main() {
|
||||
expect(scaffoldState.isDrawerOpen, true);
|
||||
});
|
||||
|
||||
testWidgets('Drawer does not open with a drag gesture when it is disabled', (WidgetTester tester) async {
|
||||
testWidgets('Drawer does not open with a drag gesture when it is disabled on mobile', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Scaffold(
|
||||
@ -1839,7 +1839,47 @@ void main() {
|
||||
await tester.dragFrom(const Offset(300, 100), const Offset(-300, 0));
|
||||
await tester.pumpAndSettle();
|
||||
expect(scaffoldState.isDrawerOpen, false);
|
||||
});
|
||||
}, variant: TargetPlatformVariant.mobile());
|
||||
|
||||
testWidgets('Drawer does not open with a drag gesture on dekstop', (WidgetTester tester) async {
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: Scaffold(
|
||||
drawer: const Drawer(
|
||||
child: Text('Drawer'),
|
||||
),
|
||||
body: const Text('Scaffold Body'),
|
||||
appBar: AppBar(
|
||||
centerTitle: true,
|
||||
title: const Text('Title'),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
final ScaffoldState scaffoldState = tester.state(find.byType(Scaffold));
|
||||
expect(scaffoldState.isDrawerOpen, false);
|
||||
|
||||
// Test that we cannot open the drawer with a drag gesture.
|
||||
await tester.dragFrom(const Offset(0, 100), const Offset(300, 0));
|
||||
await tester.pumpAndSettle();
|
||||
expect(scaffoldState.isDrawerOpen, false);
|
||||
|
||||
// Test that we can open the drawer with a tap gesture on drawer icon button.
|
||||
final Finder drawerOpenButton = find.byType(IconButton).first;
|
||||
await tester.tap(drawerOpenButton);
|
||||
await tester.pumpAndSettle();
|
||||
expect(scaffoldState.isDrawerOpen, true);
|
||||
|
||||
// Test that we cannot close the drawer with a drag gesture.
|
||||
await tester.dragFrom(const Offset(300, 100), const Offset(-300, 0));
|
||||
await tester.pumpAndSettle();
|
||||
expect(scaffoldState.isDrawerOpen, true);
|
||||
|
||||
// Test that we can close the drawer with a tap gesture in the body.
|
||||
await tester.tapAt(const Offset(500, 300));
|
||||
await tester.pumpAndSettle();
|
||||
expect(scaffoldState.isDrawerOpen, false);
|
||||
}, variant: TargetPlatformVariant.desktop());
|
||||
|
||||
testWidgets('End drawer does not open with a drag gesture when it is disabled', (WidgetTester tester) async {
|
||||
late double screenWidth;
|
||||
|
Loading…
Reference in New Issue
Block a user