fix: Android list jitter on prepend with maintainVisibleContentPosition - #536
Open
Critteros wants to merge 1 commit into
Open
fix: Android list jitter on prepend with maintainVisibleContentPosition#536Critteros wants to merge 1 commit into
Critteros wants to merge 1 commit into
Conversation
|
Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits. |
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.
Fixes #535
Problem
On Android with
maintainVisibleContentPosition, the list shifts by 1 to 2 px onevery prepend
Cause
The native MVCP helper anchors on the hidden
ScrollAdjustview and scrolls by themovement of that anchor. The anchor and the items rounded to the pixel grid differently:
top = bias + scrollAdjustwithbias = 1e7. Yoga stores layoutvalues as 32-bit floats. At 1e7 dp the float step is 1 dp, so the anchor could only
move in whole dp and fractional adjust values were lost
roundSizesnapped item sizes to 1/8 dp. On a 3x screen that is a fractional numberof physical pixels, so items moved by fractional pixel amounts
With 100.875 dp rows at scale 3, the anchor moved by 300 or 303 px while the items
moved by 302 or 303 px. The difference is the visible jitter
Fix
biasis now1e6. At 1e6 dp the float32 step is 0.0625 dp, which keeps the floaterror under half a physical pixel at all real densities. The anchor still sits after
all real items until the content is more than 1e6 dp tall (about 10,000 mounted
items at 100 dp each)
roundSizenow floors sizes to the physical pixel grid viaPixelRatio.get()instead of 1/8 dp. Every adjust value is then a whole number of pixels, so a prepend
moves the anchor and the items by the same number of pixels
PixelRatiostub now readswindow.devicePixelRatioBoth fixes are needed. With the bias change alone, the anchor and the items still
round to the pixel grid independently and each prepend leaves a 1 px shift
Measurements
30 s screen recordings under prepend traffic on a 480 dpi emulator (Pixel 9 Pro,
API 36, RN 0.83.6), comparing each frame with the previous one:
bias = 1e6only