Add pointer type detection for Swipeable

This commit is contained in:
Inex Code 2020-10-06 20:56:29 +03:00
parent 3ee20eb07c
commit de41700741

View file

@ -1,3 +1,4 @@
import 'dart:ui';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -54,6 +55,11 @@ class Swipeable extends StatefulWidget {
this.movementDuration = const Duration(milliseconds: 200), this.movementDuration = const Duration(milliseconds: 200),
this.crossAxisEndOffset = 0.0, this.crossAxisEndOffset = 0.0,
this.dragStartBehavior = DragStartBehavior.start, this.dragStartBehavior = DragStartBehavior.start,
this.allowedPointerKinds = const {
PointerDeviceKind.invertedStylus,
PointerDeviceKind.stylus,
PointerDeviceKind.touch
},
}) : assert(key != null), }) : assert(key != null),
assert(secondaryBackground == null || background != null), assert(secondaryBackground == null || background != null),
assert(dragStartBehavior != null), assert(dragStartBehavior != null),
@ -125,6 +131,11 @@ class Swipeable extends StatefulWidget {
/// it is positive or negative. /// it is positive or negative.
final double crossAxisEndOffset; final double crossAxisEndOffset;
/// Defines pointer types which are allowed to trigger swipe gesture.
///
/// Defaults to {PointerDeviceKind.touch, PointerDeviceKind.invertedStylus, PointerDeviceKind.stylus}
final Set<PointerDeviceKind> allowedPointerKinds;
/// Determines the way that drag start behavior is handled. /// Determines the way that drag start behavior is handled.
/// ///
/// If set to [DragStartBehavior.start], the drag gesture used to dismiss a /// If set to [DragStartBehavior.start], the drag gesture used to dismiss a
@ -192,6 +203,8 @@ class _SwipeableState extends State<Swipeable>
bool _dragUnderway = false; bool _dragUnderway = false;
Size _sizePriorToCollapse; Size _sizePriorToCollapse;
bool _isTouch = true;
@override @override
bool get wantKeepAlive => _moveController?.isAnimating == true; bool get wantKeepAlive => _moveController?.isAnimating == true;
@ -230,6 +243,12 @@ class _SwipeableState extends State<Swipeable>
return size.width; return size.width;
} }
void _handlePointerDown(PointerDownEvent event) {
setState(() {
_isTouch = widget.allowedPointerKinds.contains(event.kind);
});
}
void _handleDragStart(DragStartDetails details) { void _handleDragStart(DragStartDetails details) {
_dragUnderway = true; _dragUnderway = true;
if (_moveController.isAnimating) { if (_moveController.isAnimating) {
@ -447,13 +466,16 @@ class _SwipeableState extends State<Swipeable>
]); ]);
} }
// We are not swiping but we may be being dragging in widget.direction. // We are not swiping but we may be being dragging in widget.direction.
return GestureDetector( return Listener(
onHorizontalDragStart: _handleDragStart, onPointerDown: _handlePointerDown,
onHorizontalDragUpdate: _handleDragUpdate, child: GestureDetector(
onHorizontalDragEnd: _handleDragEnd, onHorizontalDragStart: _isTouch ? _handleDragStart : null,
onHorizontalDragUpdate: _isTouch ? _handleDragUpdate : null,
onHorizontalDragEnd: _isTouch ? _handleDragEnd : null,
behavior: HitTestBehavior.opaque, behavior: HitTestBehavior.opaque,
child: content, child: content,
dragStartBehavior: widget.dragStartBehavior, dragStartBehavior: widget.dragStartBehavior,
),
); );
} }
} }