-
Notifications
You must be signed in to change notification settings - Fork 29.8k
Make Scrollable's free scroll initial velocity matches that of iOS #60501
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Make Scrollable's free scroll initial velocity matches that of iOS #60501
Conversation
|
Good job! I tested it with the scroll_overlay PR#2 project including the changes in #59623. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The general approach (e.g. final Offset estimatedVelocity = _previousVelocityAt(-2) * 0.6 + _previousVelocityAt(-1) * 0.35 + _previousVelocityAt(0) * 0.05;) lgtm
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this will be the first place a user is exposed to the term "velocity tracker", describe what it is or reference another doc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe briefly describe what's special about iOS scroll velocity to help bootstrap the next maintainer
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's still not too clear what the difference is and why this needs to be a separate class rather than changing VelocityTracker.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean the difference in terms of the strategies used? Does
/// A [VelocityTracker] subclass that employs a weighted average strategy to
/// estimate the velocity of the associated pointer, to match iOS scroll view's
/// fling velocity calculation.
sound better?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As opposed to what though. I was looking for a text that saves the next maintainer from seeing thing as redundant, try to merge the 2 classes into one, spend 2 hours and then realized that the approach for the 2 are conceptually different (which the maintainer could have discovered in 10s by reading this text)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a simple comparison of the 2 velocity tracker classes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why this name? Either somehow describe the "free scroll start" nature of the velocity tracking in the class doc or just call this ios velocity tracker.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought we wanted to avoid having iOS in the name? Would be nice to know that I was mistaken.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure I understood this comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also seems like you're always using exactly 3 samples no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"4 _PointAtTime samples" is what I meant
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Horizontal/VerticalDragGestureRecognizer.isFlingGesture has a threshold for VelocityEstimate.offset for it to be a fling:
https://api.flutter.dev/flutter/gestures/VerticalDragGestureRecognizer/isFlingGesture.html
Initially I used 4 samples and that broke some tests so I had to record more points. Will point to VerticalDragGestureRecognizer.isFlingGesture in the comments.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sounds stronger than what the code seems to be doing. You're just weighing the initial velocity more rather than matching the initial velocity no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was trying to say this is the velocity of the scroll view not that of the gesture. Reworded.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"initial free scrolling speed" is a bit vague
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add to the velocity_tracker_bench microbenchmark too
99b303a to
f793210
Compare
|
fly-by comment: The analyzer is complaining. |
xster
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sorry I was out last few weeks. Thanks for the clean up! LGTM
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's still not too clear what the difference is and why this needs to be a separate class rather than changing VelocityTracker.
|
(PR triage): looks like some nested scrollview tests are failing. |
8db3b82 to
0dcec67
Compare
|
Had to use microseconds instead of milliseconds in |
|
@xster @goderbauer should be ready for review now. |
a8d0d75 to
b8c6c9c
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
<optional at this point, up to your judgement> can this just be done by composition? i.e. most platforms use a VelocityTracker with a VelocitySampleScorer of [1, 1, 1, 1, ...] and iOS uses a VelocityTracker with a VelocitySampleScorere of [8, 5, 2, 1] or something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You mean the weighted average can be expressed in terms of a least-squares estimator? Not sure how I can achieve that, could you elaborate?
|
LGTM. Up to you at this point if you want to use composition or just have 2 classes. |
3820762 to
97e257b
Compare
|
This pull request is not suitable for automatic merging in its current state.
|
goderbauer
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
| this.dragStartBehavior = DragStartBehavior.start, | ||
| this.velocityTrackerBuilder = _defaultBuilder, | ||
| }) : assert(dragStartBehavior != null), | ||
| //this.velocityTrackerBuilder = velocityTrackerBuilder |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove this?

Description
This PR makes flinging velocity platform-dependent. We can't reliably correct the flinging velocity on iOS in the friction simulation because the velocity estimation is done differently on iOS. This change brings the initial scroll velocity very close to what
scrollViewWillEndDragging(_:withVelocity:targetContentOffset:)reports in the scroll_overlay app, also since the final scroll distance (the delta) of a free scroll solely depends on the initial velocity, this in theory should also make the amount the scrollable scrolls during free scrolling match iOS (it's still not as close as it could be because of pixel snapping on iOS and another minor difference in friction simulation, but from the results below it seems this should be good enough).Test results (using a modified version of the scroll_overlay app):
test run 1
In this run
scrollViewWillEndDragging(_:withVelocity:targetContentOffset:)reported an initial velocity of 4030.787700 and a scroll distance of 2008.500000, while flutter reported 4030.6899249427292 and 2266.561898725746-258.6666666666667= 2007.89523206 respectively.test run 2
this time it's 6895.866228 vs 6895.867438846153 and 3439.500000 vs 3438.69363721.
Related Issues
Fixes #11772
Related PR
adopted some changes from #59623 for better results.
Tests
I added the following tests:
FreeScrollStartVelocityTracker.getVelocity throws when no points, etc.
Checklist
Before you create this PR confirm that it meets all requirements listed below by checking the relevant checkboxes (
[x]). This will ensure a smooth and quick review process.///).flutter analyze --flutter-repo) does not report any problems on my PR.Breaking Change
Did any tests fail when you ran them? Please read Handling breaking changes.