Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
(Android/ScrollView) Fix onMomentumScrollEnd being called multiple ti…
…mes (#32433) Summary: I noticed that `onMomentumScrollEnd` is called multiple times on Android. 1. It is always called three times with the last value 2. It is sometimes called many times befire the scrolling stops when the pagingEnabled prop is true See: <img src="https://user-images.githubusercontent.com/17070498/137640334-301b32a7-3f59-403f-ba7e-a898666aaf3e.png" width="400"/> I used the following code to get the logs: ``` import React from 'react'; import {SafeAreaView, ScrollView, Text, View} from 'react-native'; const App = () => { const onMomentumScrollEnd = ({nativeEvent}) => { console.log( 'onMomentumScrollEnd', nativeEvent.contentOffset.x, nativeEvent.contentOffset.y, ); }; const onMomentumScrollBegin = ({nativeEvent}) => { console.log( 'onMomentumScrollBegin', nativeEvent.contentOffset.x, nativeEvent.contentOffset.y, ); }; return ( <SafeAreaView> <ScrollView horizontal pagingEnabled onMomentumScrollEnd={onMomentumScrollEnd} onMomentumScrollBegin={onMomentumScrollBegin}> {new Array(10).fill(0).map((_, index) => { return ( <View style={{width: 400, height: 400, backgroundColor: 'red'}} key={index}> <Text>{index}</Text> </View> ); })} </ScrollView> </SafeAreaView> ); }; export default App; ``` From what I understood: 1. We do not check that `mStableFrames` is >= 3 when emitting the event (line 798) and we keep executing the runnable, so it is emitted until `mStableFrames` equals 3. When `mStableFrames` equals 3 we stop executing the runnable (line 809). That's why it gets called 3 times. 2. When `pagingEnabled` is true, the `postOnAnimationDelayed` method is called twice (line 794 and line 806). I believe it causes the runnable to be executing too often, and the `onMomentumScrollEnd` event to be emitted too many times. I updated the code so: 1. The event is emitted only once, and at the same time we stop executing the runnable 2. The `postOnAnimationDelayed` method is called at most once per execution of the runnable ## Changelog [Android] [Fixed] - Fix ScrollView's onMomentumScrollEnd being called multiple times on Android Pull Request resolved: #32433 Test Plan: I tested using the code above with every combination of `horizontal` and `pagingEnabled` values. Reviewed By: NickGerleman Differential Revision: D47297163 Pulled By: ryancat fbshipit-source-id: 7c31175d941ff13bed20dac03fb92d2b56e94dec
- Loading branch information