Skip to content

Commit

Permalink
fix momenutm scroll end
Browse files Browse the repository at this point in the history
  • Loading branch information
Biki-das committed Nov 6, 2024
1 parent 7211119 commit 0e382c3
Show file tree
Hide file tree
Showing 6 changed files with 174 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ public class ReactHorizontalScrollView extends HorizontalScrollView
private boolean mDragging;
private boolean mPagingEnabled = false;
private @Nullable Runnable mPostTouchRunnable;
private @Nullable Runnable mPostSmoothScrollRunnable;
private boolean mRemoveClippedSubviews;
private boolean mScrollEnabled = true;
private boolean mPreventReentry = false;
Expand Down Expand Up @@ -926,6 +927,7 @@ private void handlePostTouchScrolling(int velocityX, int velocityY) {
}

if (mSendMomentumEvents) {
enableFpsListener();
ReactScrollViewHelper.emitScrollMomentumBeginEvent(this, velocityX, velocityY);
}

Expand Down Expand Up @@ -971,7 +973,6 @@ public void run() {
nativeAnimated.userDrivenScrollEnded(ReactHorizontalScrollView.this.getId());
}
}
disableFpsListener();
} else {
if (mPagingEnabled && !mSnappingToPage) {
// If we have pagingEnabled and we have not snapped to the page
Expand All @@ -990,6 +991,34 @@ public void run() {
this, mPostTouchRunnable, ReactScrollViewHelper.MOMENTUM_DELAY);
}

public void handleSmoothScrollMomentumEvents() {
if (!mSendMomentumEvents || null != mPostSmoothScrollRunnable) {
return;
}

enableFpsListener();
mActivelyScrolling = false;
mPostSmoothScrollRunnable = new Runnable() {

@Override
public void run() {
if (mActivelyScrolling) {
// We are still scrolling so we just post to check again a frame later
mActivelyScrolling = false;
ViewCompat.postOnAnimationDelayed(
ReactHorizontalScrollView.this, this, ReactScrollViewHelper.MOMENTUM_DELAY);
} else {
ReactScrollViewHelper.emitScrollMomentumEndEvent(ReactHorizontalScrollView.this);
ReactHorizontalScrollView.this.mPostSmoothScrollRunnable = null;
disableFpsListener();
}
}
};
ViewCompat.postOnAnimationDelayed(
ReactHorizontalScrollView.this, mPostSmoothScrollRunnable, ReactScrollViewHelper.MOMENTUM_DELAY);

}

private void cancelPostTouchScrolling() {
if (mPostTouchRunnable != null) {
removeCallbacks(mPostTouchRunnable);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -214,8 +214,10 @@ public void scrollTo(
scrollView.abortAnimation();
if (data.mAnimated) {
scrollView.reactSmoothScrollTo(data.mDestX, data.mDestY);
scrollView.handleSmoothScrollMomentumEvents();
} else {
scrollView.scrollTo(data.mDestX, data.mDestY);
ReactScrollViewHelper.emitScrollMomentumEndEvent(scrollView);
}
}

Expand All @@ -235,8 +237,10 @@ public void scrollToEnd(
scrollView.abortAnimation();
if (data.mAnimated) {
scrollView.reactSmoothScrollTo(right, scrollView.getScrollY());
scrollView.handleSmoothScrollMomentumEvents();
} else {
scrollView.scrollTo(right, scrollView.getScrollY());
ReactScrollViewHelper.emitScrollMomentumEndEvent(scrollView);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ public class ReactScrollView extends ScrollView
private boolean mDragging;
private boolean mPagingEnabled = false;
private @Nullable Runnable mPostTouchRunnable;
private @Nullable Runnable mPostSmoothScrollRunnable;
private boolean mRemoveClippedSubviews;
private boolean mScrollEnabled = true;
private boolean mPreventReentry = false;
Expand Down Expand Up @@ -733,7 +734,6 @@ public void run() {
mPostTouchRunnable = null;
if (mSendMomentumEvents) {
ReactScrollViewHelper.emitScrollMomentumEndEvent(ReactScrollView.this);
}
ReactContext context = (ReactContext) getContext();
if (context != null) {
NativeAnimatedModule nativeAnimated =
Expand All @@ -742,7 +742,8 @@ public void run() {
nativeAnimated.userDrivenScrollEnded(ReactScrollView.this.getId());
}
}
disableFpsListener();
disableFpsListener();
}
} else {
if (mPagingEnabled && !mSnappingToPage) {
// If we have pagingEnabled and we have not snapped to the page
Expand All @@ -761,6 +762,35 @@ public void run() {
this, mPostTouchRunnable, ReactScrollViewHelper.MOMENTUM_DELAY);
}

public void handleSmoothScrollMomentumEvents() {
if (!mSendMomentumEvents || null != mPostSmoothScrollRunnable) {
return;
}

enableFpsListener();
mActivelyScrolling = false;
mPostSmoothScrollRunnable = new Runnable() {

@Override
public void run() {
if (mActivelyScrolling) {
// We are still scrolling so we just post to check again a frame later
mActivelyScrolling = false;
ViewCompat.postOnAnimationDelayed(
ReactScrollView.this, this, ReactScrollViewHelper.MOMENTUM_DELAY);
} else {
// There has not been a scroll update since the last time this Runnable executed.
ReactScrollViewHelper.emitScrollMomentumEndEvent(ReactScrollView.this);
ReactScrollView.this.mPostSmoothScrollRunnable = null;
disableFpsListener();
}
}
};
ViewCompat.postOnAnimationDelayed(
ReactScrollView.this, mPostSmoothScrollRunnable, ReactScrollViewHelper.MOMENTUM_DELAY);

}

private void cancelPostTouchScrolling() {
if (mPostTouchRunnable != null) {
removeCallbacks(mPostTouchRunnable);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,8 +228,10 @@ public void scrollTo(
scrollView.abortAnimation();
if (data.mAnimated) {
scrollView.reactSmoothScrollTo(data.mDestX, data.mDestY);
scrollView.handleSmoothScrollMomentumEvents();
} else {
scrollView.scrollTo(data.mDestX, data.mDestY);
ReactScrollViewHelper.emitScrollMomentumEndEvent(scrollView);
}
}

Expand Down
14 changes: 14 additions & 0 deletions packages/rn-tester/js/examples/FlatList/FlatList-basic.js
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ class FlatListExample extends React.PureComponent<Props, State> {
this._listRef?.scrollToIndex({viewPosition: 0.5, index: Number(text)});
};

_onChangeScrollOffset = (text: mixed) => {
this._listRef?.scrollToOffset({offset: Number(text), animated: false});
};

// $FlowFixMe[missing-local-annot]
_scrollPos = new Animated.Value(0);
// $FlowFixMe[missing-local-annot]
Expand Down Expand Up @@ -166,6 +170,10 @@ class FlatListExample extends React.PureComponent<Props, State> {
onChangeText={this._onChangeScrollToIndex}
placeholder="scrollToIndex..."
/>
<PlainInput
onChangeText={this._onChangeScrollOffset}
placeholder="scrollToOffset..."
/>
</View>
<View style={styles.options}>
{renderSmallSwitchOption(
Expand Down Expand Up @@ -282,6 +290,12 @@ class FlatListExample extends React.PureComponent<Props, State> {
onScroll={
this.state.horizontal ? this._scrollSinkX : this._scrollSinkY
}
onMomentumScrollEnd={() => {
console.log('onMomentumScrollEnd');
}}
onMomentumScrollBegin={e => {
console.log('onMomentumScrollBegin', e.nativeEvent);
}}
onScrollToIndexFailed={this._onScrollToIndexFailed}
onViewableItemsChanged={this._onViewableItemsChanged}
ref={this._captureRef}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,11 @@ const {
StyleSheet,
Text,
TouchableOpacity,
View,
Button,
} = require('react-native');

const nullthrows = require('nullthrows');
const NUM_ITEMS = 20;

class ScrollViewSimpleExample extends React.Component<{...}> {
Expand All @@ -38,9 +41,26 @@ class ScrollViewSimpleExample extends React.Component<{...}> {

render(): React.Node {
// One of the items is a horizontal scroll view
let _scrollView: ?React.ElementRef<typeof ScrollView>;
let _horizontalScrollView1: ?React.ElementRef<typeof ScrollView>;
let _horizontalScrollView2: ?React.ElementRef<typeof ScrollView>;
const items = this.makeItems(NUM_ITEMS, styles.itemWrapper);
items[4] = (
<ScrollView key={'scrollView'} horizontal={true}>
<ScrollView
ref={scrollView => {
_horizontalScrollView1 = scrollView;
}}
key={'scrollView'}
horizontal={true}
onMomentumScrollEnd={() => {
console.log('First Horizontal ScrollView onMomentumScrollEnd');
}}
onMomentumScrollBegin={e => {
console.log(
'First Horizontal ScrollView onMomentumScrollBegin',
e.nativeEvent,
);
}}>
{this.makeItems(NUM_ITEMS, [
styles.itemWrapper,
styles.horizontalItemWrapper,
Expand All @@ -49,10 +69,22 @@ class ScrollViewSimpleExample extends React.Component<{...}> {
);
items.push(
<ScrollView
ref={scrollView => {
_horizontalScrollView2 = scrollView;
}}
key={'scrollViewSnap'}
horizontal
snapToInterval={210.0}
pagingEnabled>
pagingEnabled
onMomentumScrollEnd={() => {
console.log('Paging Horizontal ScrollView onMomentumScrollEnd');
}}
onMomentumScrollBegin={e => {
console.log(
'Paging Horizontal ScrollView onMomentumScrollBegin',
e.nativeEvent,
);
}}>
{this.makeItems(NUM_ITEMS, [
styles.itemWrapper,
styles.horizontalItemWrapper,
Expand Down Expand Up @@ -100,17 +132,71 @@ class ScrollViewSimpleExample extends React.Component<{...}> {
</ScrollView>,
);

const verticalScrollView = (
<ScrollView style={styles.verticalScrollView}>{items}</ScrollView>
return (
<View style={styles.container}>
<View style={styles.options}>
<Button
title="Animated Scroll to top"
onPress={() => {
nullthrows(_scrollView).scrollTo({x: 0, y: 0, animated: true});
nullthrows(_horizontalScrollView1).scrollTo({
x: 0,
y: 0,
animated: true,
});
nullthrows(_horizontalScrollView2).scrollTo({
x: 0,
y: 0,
animated: true,
});
}}
/>
<Button
title="Animated Scroll to End"
onPress={() => {
nullthrows(_scrollView).scrollToEnd({animated: true});
nullthrows(_horizontalScrollView1).scrollToEnd({animated: true});
nullthrows(_horizontalScrollView2).scrollToEnd({animated: true});
}}
color={'blue'}
/>
</View>
<ScrollView
ref={scrollView => {
_scrollView = scrollView;
}}
style={styles.verticalScrollView}
onMomentumScrollEnd={() => {
console.log('Vertical ScrollView onMomentumScrollEnd');
}}
onMomentumScrollBegin={e => {
console.log(
'Vertical ScrollView onMomentumScrollBegin',
e.nativeEvent,
);
}}>
{items}
</ScrollView>
</View>
);

return verticalScrollView;
}
}

const styles = StyleSheet.create({
container: {
backgroundColor: 'rgb(239, 239, 244)',
flex: 1,
},
verticalScrollView: {
margin: 10,
backgroundColor: 'white',
flexGrow: 1,
},
options: {
flexDirection: 'row',
flexWrap: 'wrap',
alignItems: 'center',
justifyContent: 'center',
},
itemWrapper: {
backgroundColor: '#dddddd',
Expand Down

0 comments on commit 0e382c3

Please sign in to comment.