bolan9999 / react-native-largelist

The best large list component for React Native.
https://bolan9999.github.io/react-native-largelist/
MIT License
2.32k stars 261 forks source link

Swapping operation seems to happen too 'close' to the scroll #468

Open zzorba opened 2 years ago

zzorba commented 2 years ago

Thank you for this library, I spent yesterday diving deep into it and wanted to say how thankful I am for both this and spring-scrollview.

When trying to get smooth scrolling/swapping, I noticed that the 'break' points for when the swapping of a Group from one set of data to the next was happening at about 1 screen height before the 'next' group would appear on the screen.

https://github.com/bolan9999/react-native-largelist/blob/d93c8985fadafc9f84530bdadc3d63222e1ac10f/src/LargeList.js#L89

https://github.com/bolan9999/react-native-largelist/blob/d93c8985fadafc9f84530bdadc3d63222e1ac10f/src/LargeList.js#L130-L131

With this default, I was noticing a fair amount of swapping/redrawing as it scrolled. This issue is slightly more prominent on android, but with fast momentum scrolling I was getting a great deal of clipping on both platforms.

I tried adjusting this slightly to be a calculation based on the number of groups / size of groups present, i.e. try to perform the swap at the halfway point between groups.

    const wrapperHeight = idx(() => this._size.height, 700);
    const totalGroupHeight = groupMinHeight * (groupCount / 2);
    const pageHeight = Math.max(totalGroupHeight, wrapperHeight);

And then pageHeight is used instead of wrapperHeight. With this config and about 12-20 groups + a groupMinHeight of height/2, I was seeing much smoother scrolling on both platforms. There still seems to be an issue where Android 'updates' while the Animated.View are offscreen don't actually update until it enters the screen when scrolling fast, but some indications say this is an android optimization of some sort that is hard to get around.

What do you think, did I misunderstand this code or is there a reason that the swapping was always happing so close to the scrolling.

bolan9999 commented 2 years ago

groupCount?: number; The group count (not section) of the rendered content. default value is 4, set it larger, eg 6 or 8. groupMinHeight?: number; The min group height of the rendered content. default value is screenHeight/3. can be screenHeight or more.

zzorba commented 2 years ago

Yeah, I see how these both control the number of groups / size of the groups.

What struck me as odd though was that regardless of how many groups you have / how large the groups are, the 'animated position swap' always happens when it is 1 screen height away. I'm talking about the calculation within Group, when currentIndex moves from showing content index 0 to content index 1, and the Animated.View interpolates it into the next position.

As a concrete example, say I have 20 groups each of height/2 -- creating a content buffer of ~ 10 * height. Even in this situation, the 'animated swap' will happen when you are 90% of the way to the point where the next currentIndex grouping would need to be shown.