@@ -147,6 +147,14 @@ abstract class DragGestureRecognizer extends OneSequenceGestureRecognizer {
147147 /// The distance traveled by the pointer since the last update is provided in
148148 /// the callback's `details` argument, which is a [DragUpdateDetails] object.
149149 ///
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+ ///
150158 /// See also:
151159 ///
152160 /// * [allowedButtonsFilter] , which decides which button will be allowed.
@@ -162,6 +170,14 @@ abstract class DragGestureRecognizer extends OneSequenceGestureRecognizer {
162170 /// The velocity is provided in the callback's `details` argument, which is a
163171 /// [DragEndDetails] object.
164172 ///
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+ ///
165181 /// See also:
166182 ///
167183 /// * [allowedButtonsFilter] , which decides which button will be allowed.
@@ -258,6 +274,13 @@ abstract class DragGestureRecognizer extends OneSequenceGestureRecognizer {
258274 /// inertia, for example.
259275 bool isFlingGesture (VelocityEstimate estimate, PointerDeviceKind kind);
260276
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+
261284 Offset _getDeltaForDetails (Offset delta);
262285 double ? _getPrimaryValueFromOffset (Offset value);
263286 bool _hasSufficientGlobalDistanceToAccept (PointerDeviceKind pointerDeviceKind, double ? deviceTouchSlop);
@@ -504,33 +527,21 @@ abstract class DragGestureRecognizer extends OneSequenceGestureRecognizer {
504527 }
505528
506529 final VelocityTracker tracker = _velocityTrackers[pointer]! ;
530+ final VelocityEstimate ? estimate = tracker.getVelocityEstimate ();
507531
508- final DragEndDetails details;
532+ DragEndDetails ? details;
509533 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.' ;
522536 } 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.' ;
532541 }
533- invokeCallback <void >('onEnd' , () => onEnd !(details), debugReport: debugReport);
542+ details ?? = DragEndDetails (primaryVelocity: 0.0 );
543+
544+ invokeCallback <void >('onEnd' , () => onEnd !(details! ), debugReport: debugReport);
534545 }
535546
536547 void _checkCancel () {
@@ -578,6 +589,19 @@ class VerticalDragGestureRecognizer extends DragGestureRecognizer {
578589 return estimate.pixelsPerSecond.dy.abs () > minVelocity && estimate.offset.dy.abs () > minDistance;
579590 }
580591
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+
581605 @override
582606 bool _hasSufficientGlobalDistanceToAccept (PointerDeviceKind pointerDeviceKind, double ? deviceTouchSlop) {
583607 return _globalDistanceMoved.abs () > computeHitSlop (pointerDeviceKind, gestureSettings);
@@ -620,6 +644,19 @@ class HorizontalDragGestureRecognizer extends DragGestureRecognizer {
620644 return estimate.pixelsPerSecond.dx.abs () > minVelocity && estimate.offset.dx.abs () > minDistance;
621645 }
622646
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+
623660 @override
624661 bool _hasSufficientGlobalDistanceToAccept (PointerDeviceKind pointerDeviceKind, double ? deviceTouchSlop) {
625662 return _globalDistanceMoved.abs () > computeHitSlop (pointerDeviceKind, gestureSettings);
@@ -660,6 +697,16 @@ class PanGestureRecognizer extends DragGestureRecognizer {
660697 && estimate.offset.distanceSquared > minDistance * minDistance;
661698 }
662699
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+
663710 @override
664711 bool _hasSufficientGlobalDistanceToAccept (PointerDeviceKind pointerDeviceKind, double ? deviceTouchSlop) {
665712 return _globalDistanceMoved.abs () > computePanSlop (pointerDeviceKind, gestureSettings);
0 commit comments