simplify swipe recognizer

pull/2269/head
Steven Lageveen 2 weeks ago
parent ed143c0815
commit 563ad73629

@ -1,97 +1,53 @@
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
/// Custom recognizer that rejects early when initial movement is opposite
/// the allowed horizontal sign; accepts once slop is passed in allowed dir.
/// Custom recognizer that only accepts drags once movement exceeds touch slop
/// in the externally provided horizontal direction.
class DirectionalSwipeRecognizer extends HorizontalDragGestureRecognizer {
DirectionalSwipeRecognizer({required this.allowedSign, this.onAccepted});
DirectionalSwipeRecognizer({
required this.allowedSign,
this.onAccepted,
super.debugOwner,
});
/// The horizontal direction we treat as a valid swipe (+1 or -1).
int allowedSign;
final VoidCallback? onAccepted;
double _positiveExtent = 0.0;
double _negativeExtent = 0.0;
bool _accepted = false;
PointerDeviceKind? _pointerKind;
double _accumulatedDelta = 0.0;
bool _resolvedDirection = false;
void _resetState() {
_positiveExtent = 0.0;
_negativeExtent = 0.0;
_accepted = false;
_pointerKind = null;
_accumulatedDelta = 0.0;
_resolvedDirection = false;
}
@override
void addAllowedPointer(PointerDownEvent event) {
_resetState();
_pointerKind = event.kind;
super.addAllowedPointer(event);
}
double _slopFor(PointerEvent event) {
final kind = _pointerKind ?? event.kind;
return computeHitSlop(kind, gestureSettings);
}
void _accumulateDelta(double delta) {
if (delta > 0) {
_positiveExtent += delta;
} else if (delta < 0) {
_negativeExtent += -delta;
}
}
bool _resolveForDirection(int direction, PointerEvent event) {
if (direction == allowedSign) {
_accepted = true;
resolve(GestureDisposition.accepted);
onAccepted?.call();
return true;
} else if (direction == -allowedSign) {
resolve(GestureDisposition.rejected);
stopTrackingPointer(event.pointer);
_resetState();
return true;
}
return false;
}
@override
void handleEvent(PointerEvent event) {
if (!_accepted) {
if (event is PointerMoveEvent) {
_pointerKind ??= event.kind;
final deltaX = event.localDelta.dx;
if (deltaX != 0.0) {
_accumulateDelta(deltaX);
final slop = _slopFor(event);
if (_positiveExtent > slop) {
if (_resolveForDirection(1, event)) {
return;
}
} else if (_negativeExtent > slop) {
if (_resolveForDirection(-1, event)) {
return;
}
}
}
} else if (event is PointerPanZoomUpdateEvent) {
_pointerKind ??= event.kind;
final deltaX = event.panDelta.dx;
if (deltaX != 0.0) {
_accumulateDelta(deltaX);
final slop = _slopFor(event);
if (_positiveExtent > slop) {
if (_resolveForDirection(1, event)) {
return;
}
} else if (_negativeExtent > slop) {
if (_resolveForDirection(-1, event)) {
return;
}
if (
!_resolvedDirection &&
(event is PointerMoveEvent || event is PointerPanZoomUpdateEvent)) {
final deltaX = event is PointerMoveEvent
? event.localDelta.dx
: (event as PointerPanZoomUpdateEvent).panDelta.dx;
if (deltaX != 0.0) {
final logicalDelta = deltaX * allowedSign;
_accumulatedDelta += logicalDelta;
if (_accumulatedDelta.abs() > kTouchSlop) {
_resolvedDirection = true;
if (_accumulatedDelta < 0) {
resolve(GestureDisposition.rejected);
stopTrackingPointer(event.pointer);
return;
}
onAccepted?.call();
}
}
}

Loading…
Cancel
Save