From 58df074c19b546765be2b2f1f359c607a1ce048f Mon Sep 17 00:00:00 2001 From: Nikita Shanin Date: Fri, 3 Jan 2020 12:54:45 -0500 Subject: [PATCH] disable momentum scrolling for vertical ScrollView --- Libraries/Components/ScrollView/ScrollView.js | 4 ++-- React/Views/ScrollView/RCTScrollView.m | 2 ++ .../com/facebook/react/views/scroll/ReactScrollView.java | 9 +++++++++ .../react/views/scroll/ReactScrollViewManager.java | 6 ++++++ 4 files changed, 19 insertions(+), 2 deletions(-) diff --git a/Libraries/Components/ScrollView/ScrollView.js b/Libraries/Components/ScrollView/ScrollView.js index 59f5517a9d8b89..51305ff5ccef47 100644 --- a/Libraries/Components/ScrollView/ScrollView.js +++ b/Libraries/Components/ScrollView/ScrollView.js @@ -401,8 +401,8 @@ export type Props = $ReadOnly<{| /** * When true, the scroll view stops on the next index (in relation to scroll * position at release) regardless of how fast the gesture is. This can be - * used for horizontal pagination when the page is less than the width of - * the ScrollView. The default value is false. + * used for pagination when the page is less than the width of the + * horizontal ScrollView or the height of the vertical ScrollView. The default value is false. */ disableIntervalMomentum?: ?boolean, /** diff --git a/React/Views/ScrollView/RCTScrollView.m b/React/Views/ScrollView/RCTScrollView.m index 4b4d46a50a1ae5..a307cfe69e788c 100644 --- a/React/Views/ScrollView/RCTScrollView.m +++ b/React/Views/ScrollView/RCTScrollView.m @@ -738,6 +738,8 @@ - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoi if (isHorizontal) { // Use current scroll offset to determine the next index to snap to when momentum disabled targetContentOffsetAlongAxis = self.disableIntervalMomentum ? scrollView.contentOffset.x : targetContentOffset->x; + } else { + targetContentOffsetAlongAxis = self.disableIntervalMomentum ? scrollView.contentOffset.y : targetContentOffset->y; } // Offset based on desired alignment diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java index 10e1e443c95267..48664a960ca12a 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java @@ -73,6 +73,7 @@ public class ReactScrollView extends ScrollView private @Nullable String mScrollPerfTag; private @Nullable Drawable mEndBackground; private int mEndFillColor = Color.TRANSPARENT; + private boolean mDisableIntervalMomentum = false; private int mSnapInterval = 0; private float mDecelerationRate = 0.985f; private @Nullable List mSnapOffsets; @@ -135,6 +136,10 @@ private OverScroller getOverScrollerFromParent() { return scroller; } + public void setDisableIntervalMomentum(boolean disableIntervalMomentum) { + mDisableIntervalMomentum = disableIntervalMomentum; + } + public void setSendMomentumEvents(boolean sendMomentumEvents) { mSendMomentumEvents = sendMomentumEvents; } @@ -609,6 +614,10 @@ private void flingAndSnap(int velocityY) { int maximumOffset = getMaxScrollY(); int targetOffset = predictFinalScrollPosition(velocityY); + if (mDisableIntervalMomentum) { + targetOffset = getScrollY(); + } + int smallerOffset = 0; int largerOffset = maximumOffset; int firstOffset = 0; diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java index d1bb2e4070cdde..0f435ad4aa612e 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java @@ -85,6 +85,12 @@ public void setDecelerationRate(ReactScrollView view, float decelerationRate) { view.setDecelerationRate(decelerationRate); } + @ReactProp(name = "disableIntervalMomentum") + public void setDisableIntervalMomentum( + ReactScrollView view, boolean disbaleIntervalMomentum) { + view.setDisableIntervalMomentum(disbaleIntervalMomentum); + } + @ReactProp(name = "snapToInterval") public void setSnapToInterval(ReactScrollView view, float snapToInterval) { // snapToInterval needs to be exposed as a float because of the Javascript interface.