From 12b8d9db80e9ed41c7a9818fa5df137dd07b4746 Mon Sep 17 00:00:00 2001 From: Pascal Welsch Date: Sat, 8 Aug 2020 05:21:07 +0200 Subject: [PATCH] Reduce iOS scroll damping for lists with differently sized items (#59623) --- .../lib/src/widgets/scroll_physics.dart | 7 +++---- .../lib/src/widgets/scroll_simulation.dart | 2 ++ .../test/widgets/scroll_physics_test.dart | 20 +++++++++++++++++++ 3 files changed, 25 insertions(+), 4 deletions(-) diff --git a/packages/flutter/lib/src/widgets/scroll_physics.dart b/packages/flutter/lib/src/widgets/scroll_physics.dart index 1c1c72c590..1e9b990123 100644 --- a/packages/flutter/lib/src/widgets/scroll_physics.dart +++ b/packages/flutter/lib/src/widgets/scroll_physics.dart @@ -533,7 +533,7 @@ class BouncingScrollPhysics extends ScrollPhysics { return BouncingScrollSimulation( spring: spring, position: position.pixels, - velocity: velocity * 0.91, // TODO(abarth): We should move this constant closer to the drag end. + velocity: velocity, leadingExtent: position.minScrollExtent, trailingExtent: position.maxScrollExtent, tolerance: tolerance, @@ -549,9 +549,8 @@ class BouncingScrollPhysics extends ScrollPhysics { double get minFlingVelocity => kMinFlingVelocity * 2.0; // Methodology: - // 1- Use https://github.com/flutter/scroll_overlay to test with Flutter and - // platform scroll views superimposed. - // 2- Record incoming speed and make rapid flings in the test app. + // 1- Use https://github.com/flutter/platform_tests/tree/master/scroll_overlay to test with + // Flutter and platform scroll views superimposed. // 3- If the scrollables stopped overlapping at any moment, adjust the desired // output value of this function at that input speed. // 4- Feed new input/output set into a power curve fitter. Change function diff --git a/packages/flutter/lib/src/widgets/scroll_simulation.dart b/packages/flutter/lib/src/widgets/scroll_simulation.dart index 2ea0814e0e..efc46dbfaf 100644 --- a/packages/flutter/lib/src/widgets/scroll_simulation.dart +++ b/packages/flutter/lib/src/widgets/scroll_simulation.dart @@ -51,6 +51,8 @@ class BouncingScrollSimulation extends Simulation { _springSimulation = _overscrollSimulation(position, velocity); _springTime = double.negativeInfinity; } else { + // Taken from UIScrollView.decelerationRate (.normal = 0.998) + // 0.998^1000 = ~0.135 _frictionSimulation = FrictionSimulation(0.135, position, velocity); final double finalX = _frictionSimulation.finalX; if (velocity > 0.0 && finalX > trailingExtent) { diff --git a/packages/flutter/test/widgets/scroll_physics_test.dart b/packages/flutter/test/widgets/scroll_physics_test.dart index 18a1b9877e..fdb7a14291 100644 --- a/packages/flutter/test/widgets/scroll_physics_test.dart +++ b/packages/flutter/test/widgets/scroll_physics_test.dart @@ -97,6 +97,26 @@ void main() { ); }); + test('ScrollPhysics scrolling subclasses - Creating the simulation doesn\'t alter the velocity for time 0', () { + final ScrollMetrics position = FixedScrollMetrics( + minScrollExtent: 0.0, + maxScrollExtent: 100.0, + pixels: 20.0, + viewportDimension: 500.0, + axisDirection: AxisDirection.down, + ); + + const BouncingScrollPhysics bounce = BouncingScrollPhysics(); + const ClampingScrollPhysics clamp = ClampingScrollPhysics(); + const PageScrollPhysics page = PageScrollPhysics(); + + // Calls to createBallisticSimulation may happen on every frame (i.e. when the maxScrollExtent changes) + // Changing velocity for time 0 may cause a sudden, unwanted damping/speedup effect + expect(bounce.createBallisticSimulation(position, 1000).dx(0), moreOrLessEquals(1000)); + expect(clamp.createBallisticSimulation(position, 1000).dx(0), moreOrLessEquals(1000)); + expect(page.createBallisticSimulation(position, 1000).dx(0), moreOrLessEquals(1000)); + }); + group('BouncingScrollPhysics test', () { BouncingScrollPhysics physicsUnderTest;