Apply carriedVelocity unless substantially different (#79382)
This commit is contained in:
parent
d051336451
commit
ee921e6313
@ -274,6 +274,14 @@ class ScrollDragController implements Drag {
|
|||||||
static const Duration momentumRetainStationaryDurationThreshold =
|
static const Duration momentumRetainStationaryDurationThreshold =
|
||||||
Duration(milliseconds: 20);
|
Duration(milliseconds: 20);
|
||||||
|
|
||||||
|
/// The minimum amount of velocity needed to apply the [carriedVelocity] at
|
||||||
|
/// the end of a drag. Expressed as a factor. For example with a
|
||||||
|
/// [carriedVelocity] of 2000, we will need a velocity of at least 1000 to
|
||||||
|
/// apply the [carriedVelocity] as well. If the velocity does not meet the
|
||||||
|
/// threshold the the [carriedVelocity] is lost. Decided by fair eyeballing
|
||||||
|
/// with the scroll_overlay platform test.
|
||||||
|
static const double momentumRetainVelocityThresholdFactor = 0.5;
|
||||||
|
|
||||||
/// Maximum amount of time interval the drag can have consecutive stationary
|
/// Maximum amount of time interval the drag can have consecutive stationary
|
||||||
/// pointer update events before needing to break the
|
/// pointer update events before needing to break the
|
||||||
/// [motionStartDistanceThreshold] to start motion again.
|
/// [motionStartDistanceThreshold] to start motion again.
|
||||||
@ -390,9 +398,17 @@ class ScrollDragController implements Drag {
|
|||||||
velocity = -velocity;
|
velocity = -velocity;
|
||||||
_lastDetails = details;
|
_lastDetails = details;
|
||||||
|
|
||||||
// Build momentum only if dragging in the same direction.
|
if (_retainMomentum) {
|
||||||
if (_retainMomentum && velocity.sign == carriedVelocity!.sign)
|
// Build momentum only if dragging in the same direction.
|
||||||
velocity += carriedVelocity!;
|
final bool isFlingingInSameDirection = velocity.sign == carriedVelocity!.sign;
|
||||||
|
// Build momentum only if the velocity of the last drag was not
|
||||||
|
// substantially lower than the carried momentum.
|
||||||
|
final bool isVelocityNotSubstantiallyLessThanCarriedMomentum =
|
||||||
|
velocity.abs() > carriedVelocity!.abs() * momentumRetainVelocityThresholdFactor;
|
||||||
|
if(isFlingingInSameDirection && isVelocityNotSubstantiallyLessThanCarriedMomentum) {
|
||||||
|
velocity += carriedVelocity!;
|
||||||
|
}
|
||||||
|
}
|
||||||
delegate.goBallistic(velocity);
|
delegate.goBallistic(velocity);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,6 +178,23 @@ void main() {
|
|||||||
expect(getScrollVelocity(tester), moreOrLessEquals(1000.0));
|
expect(getScrollVelocity(tester), moreOrLessEquals(1000.0));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('A slower final fling does not apply carried momentum', (WidgetTester tester) async {
|
||||||
|
await pumpTest(tester, debugDefaultTargetPlatformOverride);
|
||||||
|
await tester.fling(find.byType(Scrollable), const Offset(0.0, -dragOffset), 1000.0);
|
||||||
|
await tester.pump(); // trigger fling
|
||||||
|
await tester.pump(const Duration(milliseconds: 10));
|
||||||
|
// Repeat the exact same motion to build momentum.
|
||||||
|
await tester.fling(find.byType(Scrollable), const Offset(0.0, -dragOffset), 1000.0);
|
||||||
|
await tester.pump(); // trigger the second fling
|
||||||
|
await tester.pump(const Duration(milliseconds: 10));
|
||||||
|
// Make a final fling that is much slower.
|
||||||
|
await tester.fling(find.byType(Scrollable), const Offset(0.0, -dragOffset), 200.0);
|
||||||
|
await tester.pump(); // trigger the third fling
|
||||||
|
await tester.pump(const Duration(milliseconds: 10));
|
||||||
|
// expect that there is no carried velocity
|
||||||
|
expect(getScrollVelocity(tester), lessThan(200.0));
|
||||||
|
}, variant: const TargetPlatformVariant(<TargetPlatform>{ TargetPlatform.iOS, TargetPlatform.macOS }));
|
||||||
|
|
||||||
testWidgets('No iOS/macOS momentum build with flings in opposite directions', (WidgetTester tester) async {
|
testWidgets('No iOS/macOS momentum build with flings in opposite directions', (WidgetTester tester) async {
|
||||||
await pumpTest(tester, debugDefaultTargetPlatformOverride);
|
await pumpTest(tester, debugDefaultTargetPlatformOverride);
|
||||||
await tester.fling(find.byType(Scrollable), const Offset(0.0, -dragOffset), 1000.0);
|
await tester.fling(find.byType(Scrollable), const Offset(0.0, -dragOffset), 1000.0);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user