@@ -147,6 +147,14 @@ abstract class DragGestureRecognizer extends OneSequenceGestureRecognizer {
147
147
/// The distance traveled by the pointer since the last update is provided in
148
148
/// the callback's `details` argument, which is a [DragUpdateDetails] object.
149
149
///
150
+ /// If this gesture recognizer recognizes movement on a single axis (a
151
+ /// [VerticalDragGestureRecognizer] or [HorizontalDragGestureRecognizer] ),
152
+ /// then `details` will reflect movement only on that axis and its
153
+ /// [DragUpdateDetails.primaryDelta] will be non-null.
154
+ /// If this gesture recognizer recognizes movement in all directions
155
+ /// (a [PanGestureRecognizer] ), then `details` will reflect movement on
156
+ /// both axes and its [DragUpdateDetails.primaryDelta] will be null.
157
+ ///
150
158
/// See also:
151
159
///
152
160
/// * [allowedButtonsFilter] , which decides which button will be allowed.
@@ -162,6 +170,14 @@ abstract class DragGestureRecognizer extends OneSequenceGestureRecognizer {
162
170
/// The velocity is provided in the callback's `details` argument, which is a
163
171
/// [DragEndDetails] object.
164
172
///
173
+ /// If this gesture recognizer recognizes movement on a single axis (a
174
+ /// [VerticalDragGestureRecognizer] or [HorizontalDragGestureRecognizer] ),
175
+ /// then `details` will reflect movement only on that axis and its
176
+ /// [DragEndDetails.primaryVelocity] will be non-null.
177
+ /// If this gesture recognizer recognizes movement in all directions
178
+ /// (a [PanGestureRecognizer] ), then `details` will reflect movement on
179
+ /// both axes and its [DragEndDetails.primaryVelocity] will be null.
180
+ ///
165
181
/// See also:
166
182
///
167
183
/// * [allowedButtonsFilter] , which decides which button will be allowed.
@@ -258,6 +274,13 @@ abstract class DragGestureRecognizer extends OneSequenceGestureRecognizer {
258
274
/// inertia, for example.
259
275
bool isFlingGesture (VelocityEstimate estimate, PointerDeviceKind kind);
260
276
277
+ /// Determines if a gesture is a fling or not, and if so its effective velocity.
278
+ ///
279
+ /// A fling calls its gesture end callback with a velocity, allowing the
280
+ /// provider of the callback to respond by carrying the gesture forward with
281
+ /// inertia, for example.
282
+ DragEndDetails ? _considerFling (VelocityEstimate estimate, PointerDeviceKind kind);
283
+
261
284
Offset _getDeltaForDetails (Offset delta);
262
285
double ? _getPrimaryValueFromOffset (Offset value);
263
286
bool _hasSufficientGlobalDistanceToAccept (PointerDeviceKind pointerDeviceKind, double ? deviceTouchSlop);
@@ -504,33 +527,21 @@ abstract class DragGestureRecognizer extends OneSequenceGestureRecognizer {
504
527
}
505
528
506
529
final VelocityTracker tracker = _velocityTrackers[pointer]! ;
530
+ final VelocityEstimate ? estimate = tracker.getVelocityEstimate ();
507
531
508
- final DragEndDetails details;
532
+ DragEndDetails ? details;
509
533
final String Function () debugReport;
510
-
511
- final VelocityEstimate ? estimate = tracker.getVelocityEstimate ();
512
- if (estimate != null && isFlingGesture (estimate, tracker.kind)) {
513
- final Velocity velocity = Velocity (pixelsPerSecond: estimate.pixelsPerSecond)
514
- .clampMagnitude (minFlingVelocity ?? kMinFlingVelocity, maxFlingVelocity ?? kMaxFlingVelocity);
515
- details = DragEndDetails (
516
- velocity: velocity,
517
- primaryVelocity: _getPrimaryValueFromOffset (velocity.pixelsPerSecond),
518
- );
519
- debugReport = () {
520
- return '$estimate ; fling at $velocity .' ;
521
- };
534
+ if (estimate == null ) {
535
+ debugReport = () => 'Could not estimate velocity.' ;
522
536
} else {
523
- details = DragEndDetails (
524
- primaryVelocity: 0.0 ,
525
- );
526
- debugReport = () {
527
- if (estimate == null ) {
528
- return 'Could not estimate velocity.' ;
529
- }
530
- return '$estimate ; judged to not be a fling.' ;
531
- };
537
+ details = _considerFling (estimate, tracker.kind);
538
+ debugReport = (details != null )
539
+ ? () => '$estimate ; fling at ${details !.velocity }.'
540
+ : () => '$estimate ; judged to not be a fling.' ;
532
541
}
533
- invokeCallback <void >('onEnd' , () => onEnd !(details), debugReport: debugReport);
542
+ details ?? = DragEndDetails (primaryVelocity: 0.0 );
543
+
544
+ invokeCallback <void >('onEnd' , () => onEnd !(details! ), debugReport: debugReport);
534
545
}
535
546
536
547
void _checkCancel () {
@@ -578,6 +589,19 @@ class VerticalDragGestureRecognizer extends DragGestureRecognizer {
578
589
return estimate.pixelsPerSecond.dy.abs () > minVelocity && estimate.offset.dy.abs () > minDistance;
579
590
}
580
591
592
+ @override
593
+ DragEndDetails ? _considerFling (VelocityEstimate estimate, PointerDeviceKind kind) {
594
+ if (! isFlingGesture (estimate, kind)) {
595
+ return null ;
596
+ }
597
+ final double maxVelocity = maxFlingVelocity ?? kMaxFlingVelocity;
598
+ final double dy = clampDouble (estimate.pixelsPerSecond.dy, - maxVelocity, maxVelocity);
599
+ return DragEndDetails (
600
+ velocity: Velocity (pixelsPerSecond: Offset (0 , dy)),
601
+ primaryVelocity: dy,
602
+ );
603
+ }
604
+
581
605
@override
582
606
bool _hasSufficientGlobalDistanceToAccept (PointerDeviceKind pointerDeviceKind, double ? deviceTouchSlop) {
583
607
return _globalDistanceMoved.abs () > computeHitSlop (pointerDeviceKind, gestureSettings);
@@ -620,6 +644,19 @@ class HorizontalDragGestureRecognizer extends DragGestureRecognizer {
620
644
return estimate.pixelsPerSecond.dx.abs () > minVelocity && estimate.offset.dx.abs () > minDistance;
621
645
}
622
646
647
+ @override
648
+ DragEndDetails ? _considerFling (VelocityEstimate estimate, PointerDeviceKind kind) {
649
+ if (! isFlingGesture (estimate, kind)) {
650
+ return null ;
651
+ }
652
+ final double maxVelocity = maxFlingVelocity ?? kMaxFlingVelocity;
653
+ final double dx = clampDouble (estimate.pixelsPerSecond.dx, - maxVelocity, maxVelocity);
654
+ return DragEndDetails (
655
+ velocity: Velocity (pixelsPerSecond: Offset (dx, 0 )),
656
+ primaryVelocity: dx,
657
+ );
658
+ }
659
+
623
660
@override
624
661
bool _hasSufficientGlobalDistanceToAccept (PointerDeviceKind pointerDeviceKind, double ? deviceTouchSlop) {
625
662
return _globalDistanceMoved.abs () > computeHitSlop (pointerDeviceKind, gestureSettings);
@@ -660,6 +697,16 @@ class PanGestureRecognizer extends DragGestureRecognizer {
660
697
&& estimate.offset.distanceSquared > minDistance * minDistance;
661
698
}
662
699
700
+ @override
701
+ DragEndDetails ? _considerFling (VelocityEstimate estimate, PointerDeviceKind kind) {
702
+ if (! isFlingGesture (estimate, kind)) {
703
+ return null ;
704
+ }
705
+ final Velocity velocity = Velocity (pixelsPerSecond: estimate.pixelsPerSecond)
706
+ .clampMagnitude (minFlingVelocity ?? kMinFlingVelocity, maxFlingVelocity ?? kMaxFlingVelocity);
707
+ return DragEndDetails (velocity: velocity);
708
+ }
709
+
663
710
@override
664
711
bool _hasSufficientGlobalDistanceToAccept (PointerDeviceKind pointerDeviceKind, double ? deviceTouchSlop) {
665
712
return _globalDistanceMoved.abs () > computePanSlop (pointerDeviceKind, gestureSettings);
0 commit comments