Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/46487
Changelog: [General][Fixed] Fixed accuracy of FlatList estimations to determine what elements are visible in the rendering window.
This fixes a bug in FlatList where it thinks that some elements are visible in the rendering window, when they're not. Specifically, if a cell hasn't been laid out yet, it ignores all the information it already has on the ones that had, and estimates its position and offset based on the estimated size of the cells. In this case, if the first element has a larger offset because the list has a header, that offset is ignored in this case.
One observed result of this is that in a list where there's a header and a single cell that occupy the whole rendering window, FlatList thinks it needs to pre-render an additional element because the header is ignored.
Reviewed By: NickGerleman
Differential Revision: D62649060
fbshipit-source-id: 437bae79916707ca1d08784190508a9f7e36688e
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/39646
We can dramatically simplify this code and remove quirks/hacks, now that we can assume layout events are always fired top down.
Changelog: [Internal]
Reviewed By: yungsters
Differential Revision: D49628669
fbshipit-source-id: 7de5bbc4597eba1c59aaa7672c70e76d2786c7ef
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/39335
In RTL we must have scrollview content length in order to resolve cell metrics. This means that on Paper, where layout events are bottom up, we cannot immediately calculate viewability in response to cell metric changes, as we may not yet have an accurate length of laid out list content.
This change makes us defer calculation of viewability changes in this case via `setTimeout()`, to run in a single batch after the next layout events are fired.
---
We need container dimensions to resolve the right-edge relative child directions. It is tricky to do this at a guaranteed right time with onLayout model on Paper.
When we are laying out children, the first layout on Paper looks like:
1. Child is laid out
2. Container is laid out
However, we will never see container onLayout if a child layout does not change the dimensions of the parent container. This will be the common case of subsequent child layouts, where the spacer size was accurate.
I.e. we may or may not ever see content laid out, but can only rely on having both offsets be up to date if we trigger calculation after the container layout would have happened. This is not an issue on Fabric where layout events are fired top-down, or for the most common cases of VirtualizedList, where we run calculations in idle batches that will happen after layout is set, but ends up causing problems for two scenarios I didn't originally account for:
We may recalculate cells to render immediately instead scheduling a later update if the list thinks blanking is immediate (high priority render). This means we cannot do an immediate update in response to cell layout, but we can in response to events batched after layout events are all dispatched, or in worst case delay in Paper RTL.
We do not batch/schedule viewability calculations in response to cell layout in the same wasy as we do for calculating cells to render, but do need them to trigger recalculation.
The way less hacky, but much more invasive solution, that would simplify a lot of this, would be to include parentWidth and parentHeight in onLayout events for Paper (and Fabric for consistency), so that we don't need to rely on event ordering, or sometimes not firing. I thought this would be too much at first, if we didn't have other use-cases, but am more and more tempted to tear down a lot of what we have here to do that instead, since this is not going to be able to rely on useLayoutEffect or IntersectionObserver in today's VirtualizedList because it will need to support Paper for the forseeable future..
Changelog:
[General][Fixed] - Fix invariant violation when using viewability callbacks with horizontal RTL FlatList on Paper
Reviewed By: yungsters
Differential Revision: D49072963
fbshipit-source-id: accd33e2c50935bb67700d94820f6418f130fe08
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38937
It is a logic error to query for list metrics when a valid list content length has not yet been observed.
An invariant is meant to catch this if it happens, but a non-default orientation causes us to zero out a value which is null, and our null check does not catch this, and we return a nonsense value.
Change from zeroing out the field to nulling it out instead.
Changelog: [Internal]
Reviewed By: lenaic
Differential Revision: D48251645
fbshipit-source-id: 5c7e16f694db4ddb0d37b6092de2e75ee8d6c7d3
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38733
I was working under the assumption that Fabric fired layout events bottom up, but it actually fires them top-down, in constrast to Paper.
Previous invalidation logic wasn't quite correct when fired bottom-up. This corrects the logic by:
1. Deriving direction based on initial event ordering
2. Use last cached contentLength if we are on Fabric (top-down)
3. Use future contentLength if we are on Paper (bottom-up)
Changelog:
[General][Fixed] - Fixup contentLength invalidation logic
Reviewed By: rozele
Differential Revision: D47978638
fbshipit-source-id: 3446d08aa34397b4e6bd9924dad0eba36a12a115
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38734
Returned measurements from the measurements cache in RTL calculate offset as distance from the left edge of the cell to the right edge of the content, when it should instead be the distance from the right edge of the cell (the logical beginning).
Changelog:
[General][Fixed] - Return right edge in RTL cell metrics
Reviewed By: lenaic
Differential Revision: D47978631
fbshipit-source-id: b0db4e9aff676c5bee81d4491f901a6bbc38e4bf
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/38529
VirtualizedList internally represents metrics along the scrolling axis using `offset` (x, y), and `length` (width, height). This one dimensional representation allows the list to be generic to being horizontal or vertical.
Right now offset conversion directly takes the `x` or `y` axis value, but this is not correct when we are using a horizontal FlatList in RTL.
This change converts most VirtualizedList code handling `offset,length` coordinates consistently flow from start to end, including in horizontal RTL and in inverted FlatList.
This is paired with a fix to Android native code in D47627115. With these together, basic Horizontal FlatList scenarios should work correctly when laid out in RTL.
Changelog:
[General][Fixed] - Fix virtualization logic with horizontal RTL lists
Reviewed By: vincentriemer
Differential Revision: D46586420
fbshipit-source-id: 79594e197d21871bb493399999e91fc0d6c7b050
Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/37777
This extracts the state and logic VirtualizedList uses to query information related to cell metrics. We will need to modify this (and other places) when fixing up RTL support for horizontal FlatList.
Changelog: [Internal]
Reviewed By: javache
Differential Revision: D46427052
fbshipit-source-id: 0a23f6c726447de0f20c583b4d507003efd6a754