mirror of
https://github.com/flutter/flutter
synced 2024-10-13 11:42:54 +00:00
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 =
|
||||
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
|
||||
/// pointer update events before needing to break the
|
||||
/// [motionStartDistanceThreshold] to start motion again.
|
||||
|
@ -390,9 +398,17 @@ class ScrollDragController implements Drag {
|
|||
velocity = -velocity;
|
||||
_lastDetails = details;
|
||||
|
||||
// Build momentum only if dragging in the same direction.
|
||||
if (_retainMomentum && velocity.sign == carriedVelocity!.sign)
|
||||
velocity += carriedVelocity!;
|
||||
if (_retainMomentum) {
|
||||
// Build momentum only if dragging in the same direction.
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -178,6 +178,23 @@ void main() {
|
|||
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 {
|
||||
await pumpTest(tester, debugDefaultTargetPlatformOverride);
|
||||
await tester.fling(find.byType(Scrollable), const Offset(0.0, -dragOffset), 1000.0);
|
||||
|
|
Loading…
Reference in a new issue