Repository navigation
Conversation
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note
This PR description is AI-generated.
Fixes #38470
Summary:
On Android, a ScrollView that moves on screen while it is being dragged stutters, and when it moves faster than the finger it stops scrolling. This happens for example when
toportransformfollows the scroll offset.android.widget.ScrollViewcomputes the drag delta from view-local touch coordinates, so the view's own movement looks like finger movement in the other direction.I added
StableTouchCoordinatesHelper. It offsets eachMotionEventby how far the view moved on screen sinceACTION_DOWNbeforeReactScrollViewandReactHorizontalScrollViewpass it to the platform scroll view and toVelocityHelper. It converts that movement into the view's own axes, so flipped lists (invertedFlatList usesscale: -1on Android) and scaled ancestors are handled. It adds the ancestors' scroll offsets back, so movement caused by nested scrolling is not compensated twice, becauseScrollViewalready handles it. I also added aMovingScrollViewExampleto RNTester.Changelog:
[ANDROID] [FIXED] - Fix ScrollView stuttering or stopping when the ScrollView moves while it is being dragged
Test Plan:
Recordings from RNTester
MovingScrollViewExampleon a Pixel 8. Each recording shows the same two drags. Left is before the fix, right is after.Multiplier 2: before, the list barely scrolls and jumps back.
Multiplier 1: before, the list scrolls less than the finger moves and stutters.
MP4 versions: multiplier 2, multiplier 1.
StableTouchCoordinatesHelperTestand the othercom.facebook.react.views.scrollunit tests pass.In RNTester
MovingScrollViewExampleon an Android 16 emulator, I made one 343 dp drag per run. These are the scroll offsets atACTION_UPin dp, two runs each (about 330 is correct):Inverted FlatList on a Pixel 8, one 404 dp drag per run (about 404 is correct):
In the nested case (
nestedScrollEnabledScrollView inside a ScrollView), outer + inner scroll was 336 and 326 dp before and 335 and 316 dp after.