Skip to content

Commit 6237cfb

Browse files
Shaninnikfacebook-github-bot
authored andcommitted
disable momentum scrolling for vertical ScrollView (#27666)
Summary: Following up changes added in #24045 I had the same use case for vertical ScrollView. This PR just enables existing `disableIntervalMomentum` property to work with vertical ScrollViews: restricts vertical pagination when page height is less than height of ScrollView. ## Changelog [General] [Changed] - changed property `disableIntervalMomentum` to work with both horizontal and vertical ScrollViews Pull Request resolved: #27666 Test Plan: No new tests at the moment `iOS` ``` All tests Test Suite RNTesterUnitTests.xctest started RCTAllocationTests ✓ testBridgeIsDeallocated (0.045 seconds) ✓ testContentViewIsInvalidated (0.006 seconds) ✓ testModuleMethodsAreDeallocated (0.002 seconds) ✓ testModulesAreDeallocated (0.022 seconds) ✓ testModulesAreInvalidated (0.017 seconds) RCTAnimationUtilsTests ✓ testClampExtrapolate (0.002 seconds) ✓ testExtendExtrapolate (0.002 seconds) ✓ testIdentityExtrapolate (0.001 seconds) ✓ testManySegments (0.003 seconds) ✓ testSimpleOneToOneMapping (0.002 seconds) ✓ testWiderInputRange (0.003 seconds) ✓ testWiderOutputRange (0.002 seconds) RCTBlobManagerTests ✓ testCreateFromParts (0.002 seconds) ✓ testRemove (0.001 seconds) ✓ testResolve (0.001 seconds) ✓ testResolveMap (0.001 seconds) ✓ testResolveURL (0.001 seconds) RCTBundleURLProviderTests ✓ testBundleURL (0.041 seconds) ✓ testIPURL (0.005 seconds) ✓ testLocalhostURL (0.005 seconds) RCTComponentPropsTests ✓ testNeedsOffscreenAlphaCompositing (0.019 seconds) ✓ testResetBackgroundColor (0.008 seconds) ✓ testResetProps (0.012 seconds) ✓ testSetProps (0.009 seconds) RCTConvert_NSURLTests ✓ test_basic (0.002 seconds) ✓ test_documentsFolder (0.001 seconds) ✓ test_filePath (0.001 seconds) ✓ test_filePathWithEncodedSpaces (0.001 seconds) ✓ test_filePathWithSpaces (0.001 seconds) ✓ test_fileURL (0.001 seconds) ✓ test_fullURL (0.001 seconds) ✓ test_imageAt2XPath (0.001 seconds) ✓ test_imageFile (0.001 seconds) ✓ test_imageURL (0.001 seconds) ✓ test_imageURLWithSpaces (0.001 seconds) ✓ test_null (0.001 seconds) ✓ test_unicodeURL (0.001 seconds) ✓ test_urlWithEncodedSpaces (0.001 seconds) ✓ test_urlWithSpaces (0.001 seconds) ✓ testDataURL (0.003 seconds) RCTConvert_YGValueTests ✓ testNumberPoints (0.002 seconds) ✓ testStringPercent (0.002 seconds) ✓ testUndefined (0.001 seconds) RCTDevMenuTests ✓ testClosingActionSheetAfterAction (0.009 seconds) ✓ testShowCreatingActionSheet (0.017 seconds) RCTEventDispatcherTests ✓ testBasicCoalescingReturnsLastEvent (0.006 seconds) ✓ testCoalescingEventIsImmediatelyDispatched (0.001 seconds) ✓ testDifferentEventTypesDontCoalesce (0.001 seconds) ✓ testDifferentViewTagsDontCoalesce (0.001 seconds) ✓ testLegacyEventsAreImmediatelyDispatched (0.001 seconds) ✓ testMultipleEventsResultInOnlyOneDispatchAfterTheFirstOne (0.001 seconds) ✓ testNonCoalescingEventIsImmediatelyDispatched (0.001 seconds) ✓ testRunningTheDispatchedBlockResultInANewOneBeingEnqueued (0.001 seconds) ✓ testSameEventTypesWithDifferentCoalesceKeysDontCoalesce (0.001 seconds) RCTFontTests ✓ testFamily (0.029 seconds) ✓ testFamilyAndStyle (0.001 seconds) ✓ testFamilyAndWeight (0.002 seconds) ✓ testFamilyStyleAndWeight (0.002 seconds) ✓ testInvalidFont (0.002 seconds) ✓ testSize (0.001 seconds) ✓ testStyle (0.003 seconds) ✓ testStyleAndWeight (0.002 seconds) ✓ testVariant (0.002 seconds) ✓ testWeight (0.002 seconds) RCTFormatErrorTests ✓ testSymbolication (0.002 seconds) RCTGzipTests ✓ testDontRezipZippedData (0.004 seconds) ✓ testGzip (0.002 seconds) ✓ testRequestBodyEncoding (0.003 seconds) RCTImageLoaderTests ✓ testImageDecoding (0.010 seconds) ✓ testImageLoaderUsesImageDecoderWithHighestPriority (0.003 seconds) ✓ testImageLoaderUsesImageURLLoaderWithHighestPriority (0.004 seconds) ✓ testImageLoading (0.004 seconds) RCTImageUtilTests ✓ testLandscapeSourceLandscapeTarget (0.001 seconds) ✓ testPortraitSourceLandscapeTarget (0.001 seconds) ✓ testPortraitSourcePortraitTarget (0.001 seconds) ✓ testRounding (0.001 seconds) ✓ testScaling (0.001 seconds) RCTJSONTests ✓ testDecodingArray (0.001 seconds) ✓ testDecodingMutableArray (0.001 seconds) ✓ testDecodingObject (0.001 seconds) ✓ testDecodingString (0.001 seconds) ✓ testEncodingArray (0.001 seconds) ✓ testEncodingNSError (0.023 seconds) ✓ testEncodingObject (0.001 seconds) ✓ testEncodingString (0.001 seconds) ✓ testErrorPointer (0.002 seconds) ✓ testLeadingWhitespace (0.001 seconds) ✓ testNaN (0.001 seconds) ✓ testNotJSONSerializable (0.001 seconds) ✓ testNotUTF8Convertible (0.004 seconds) RCTMethodArgumentTests ✓ testAttributes (0.001 seconds) ✓ testGenericArray (0.001 seconds) ✓ testGenericDictionary (0.001 seconds) ✓ testGenericSet (0.001 seconds) ✓ testNamespacedCxxStruct (0.001 seconds) ✓ testNestedGenericArray (0.001 seconds) ✓ testNewlines (0.001 seconds) ✓ testNullability (0.001 seconds) ✓ testOneArgument (0.001 seconds) ✓ testSemicolonStripping (0.001 seconds) ✓ testSpaces (0.001 seconds) ✓ testTwoArguments (0.001 seconds) ✓ testUnnamedArgs (0.001 seconds) ✓ testUntypedUnnamedArgs (0.001 seconds) ✓ testUnused (0.001 seconds) RCTModuleInitNotificationRaceTests ✓ testViewManagerNotInitializedBeforeSetBridgeModule (0.009 seconds) RCTModuleInitTests ✓ testCustomInitModuleInitializedAtBridgeStartup (0.005 seconds) ✓ testCustomSetBridgeModuleInitializedAtBridgeStartup (0.006 seconds) ✓ testExportConstantsModuleInitializedAtBridgeStartup (0.005 seconds) ✓ testInjectedModulesInitializedDuringBridgeInit (0.003 seconds) ✓ testLazyInitModuleNotInitializedDuringBridgeInit (0.005 seconds) RCTModuleMethodTests ✓ testFunctionType (0.001 seconds) ✓ testNonnull (0.001 seconds) ✓ testNumbersNonnull (0.001 seconds) ✓ testReturnsNilForDefaultFunction (0.001 seconds) ✓ testReturnsValueForSyncFunction (0.001 seconds) ✓ testReturnTypeForSyncFunction (0.001 seconds) ✓ testStructArgument (0.001 seconds) ✓ testWhitespaceTolerance (0.001 seconds) RCTMultipartStreamReaderTests ✓ testMultipleParts (0.001 seconds) ✓ testNoCloseDelimiter (0.001 seconds) ✓ testNoDelimiter (0.001 seconds) ✓ testSimpleCase (0.001 seconds) RCTNativeAnimatedNodesManagerTests ✓ testAdditionNode (0.002 seconds) ✓ testAnimationCallbackFinish (0.001 seconds) ✓ testCritcallyDampedSpringAnimation (0.003 seconds) ✓ testDecayAnimation (0.004 seconds) ✓ testDecayAnimationLoop (0.012 seconds) ✓ testFramesAnimation (0.001 seconds) ✓ testFramesAnimationLoop (0.002 seconds) ✓ testHandleStoppingAnimation (0.002 seconds) ✓ testInterpolationNode (0.002 seconds) ✓ testMultiplicationNode (0.001 seconds) ✓ testNativeAnimatedEventDoNotUpdate (0.001 seconds) ✓ testNativeAnimatedEventDoUpdate (0.002 seconds) ✓ testNodeValueListenerIfListening (0.001 seconds) ✓ testNodeValueListenerIfNotListening (0.001 seconds) ✓ testSpringAnimationLoop (0.007 seconds) ✓ testSpringTrackingRetainsSpeed (0.007 seconds) ✓ testTracking (0.002 seconds) ✓ testTrackingPausesWhenEndValueIsReached (0.001 seconds) ✓ testUnderdampedSpringAnimation (0.003 seconds) ✓ testViewReceiveUpdatesIfOneOfAnimationHasntStarted (0.001 seconds) ✓ testViewReceiveUpdatesWhenOneOfAnimationHasFinished (0.001 seconds) RCTPerformanceLoggerTests ✓ testLabelCountInSyncWithRCTPLTag (0.001 seconds) RCTShadowViewTests ✓ testAncestorCheck (0.001 seconds) ✓ testApplyingLayoutRecursivelyToShadowView (0.002 seconds) ✓ testAssignsSuggestedHeightDimension (0.001 seconds) ✓ testAssignsSuggestedWidthDimension (0.001 seconds) ✓ testDoesNotAssignSuggestedDimensionsWhenStyledWithFlexAttribute (0.001 seconds) ✓ testDoesNotOverrideDimensionStyleWithSuggestedDimensions (0.001 seconds) RCTUIManagerTests ✓ testManagingChildrenToAddRemoveAndMove (0.001 seconds) ✓ testManagingChildrenToAddViews (0.001 seconds) ✓ testManagingChildrenToRemoveViews (0.001 seconds) RCTURLUtilsTests ✓ testAppendParam (0.001 seconds) ✓ testDuplicateParamTakesLatter (0.001 seconds) ✓ testGetEncodedParam (0.001 seconds) ✓ testGetQueryParam (0.001 seconds) ✓ testIsLocalAssetsURLParam (0.001 seconds) ✓ testNilURLAppendQueryParam (0.001 seconds) ✓ testNilURLGetQueryParam (0.001 seconds) ✓ testQueryParamNotFound (0.001 seconds) ✓ testRemoveParam (0.001 seconds) ✓ testReplaceEncodedParam (0.001 seconds) ✓ testReplaceParam (0.001 seconds) RCTUnicodeDecodeTests ✓ testEmojis (0.001 seconds) ✓ testNiqqud (0.001 seconds) Executed 167 tests, with 0 failures (0 unexpected) in 0.530 (0.667) seconds ``` `Android` ``` PASS 8.4s 7 Passed 0 Skipped 0 Failed com.facebook.react.animated.NativeAnimatedInterpolationTest PASS 16.7s 23 Passed 0 Skipped 0 Failed com.facebook.react.animated.NativeAnimatedNodeTraversalTest PASS 13.5s 4 Passed 0 Skipped 0 Failed com.facebook.react.bridge.BaseJavaModuleTest PASS 341ms 4 Passed 0 Skipped 0 Failed com.facebook.react.bridge.FallbackJSBundleLoaderTest PASS <100ms 1 Passed 0 Skipped 0 Failed com.facebook.react.bridge.JavaOnlyArrayTest PASS 13.0s 10 Passed 0 Skipped 0 Failed com.facebook.react.devsupport.JSDebuggerWebSocketClientTest PASS 6.3s 4 Passed 0 Skipped 0 Failed com.facebook.react.devsupport.MultipartStreamReaderTest PASS 6.1s 5 Passed 0 Skipped 0 Failed com.facebook.react.devsupport.StackTraceHelperTest PASS 13.9s 6 Passed 0 Skipped 0 Failed com.facebook.react.modules.blob.BlobModuleTest PASS 6.7s 5 Passed 0 Skipped 0 Failed com.facebook.react.modules.camera.ImageStoreManagerTest PASS 5.2s 1 Passed 0 Skipped 0 Failed com.facebook.react.modules.clipboard.ClipboardModuleTest PASS 3.8s 5 Passed 0 Skipped 0 Failed com.facebook.react.modules.dialog.DialogModuleTest PASS <100ms 10 Passed 0 Skipped 0 Failed com.facebook.react.modules.network.HeaderUtilTest PASS 3.3s 14 Passed 0 Skipped 0 Failed com.facebook.react.modules.network.NetworkingModuleTest PASS 1.4s 9 Passed 0 Skipped 0 Failed com.facebook.react.modules.network.ProgressiveStringDecoderTest PASS 1.6s 4 Passed 0 Skipped 0 Failed com.facebook.react.modules.network.ReactCookieJarContainerTest PASS 2.2s 2 Passed 0 Skipped 0 Failed com.facebook.react.modules.share.ShareModuleTest PASS 5.1s 6 Passed 0 Skipped 0 Failed com.facebook.react.modules.storage.AsyncStorageModuleTest PASS 2.7s 9 Passed 0 Skipped 0 Failed com.facebook.react.modules.timing.TimingModuleTest PASS 9.2s 9 Passed 0 Skipped 0 Failed com.facebook.react.packagerconnection.JSPackagerClientTest PASS 7.3s 4 Passed 0 Skipped 0 Failed com.facebook.react.uimanager.layoutanimation.InterpolatorTypeTest PASS 8.9s 2 Passed 0 Skipped 0 Failed com.facebook.react.uimanager.BaseViewManagerTest PASS 6.7s 4 Passed 0 Skipped 0 Failed com.facebook.react.uimanager.MatrixMathHelperTest PASS 8.8s 3 Passed 0 Skipped 0 Failed com.facebook.react.uimanager.SimpleViewPropertyTest PASS <100ms 1 Passed 0 Skipped 0 Failed com.facebook.react.util.JSStackTraceTest PASS 9.5s 1 Passed 0 Skipped 0 Failed com.facebook.react.views.image.ImageResizeModeTest PASS 15.7s 4 Passed 0 Skipped 0 Failed com.facebook.react.views.image.ReactImagePropertyTest PASS 9.2s 4 Passed 0 Skipped 0 Failed com.facebook.react.CompositeReactPackageTest PASS 9.2s 2 Passed 0 Skipped 0 Failed com.facebook.react.RootViewTest ``` Differential Revision: D19576473 Pulled By: shergin fbshipit-source-id: 35a6bce9f7dd3efec0cfcdbb00796852e1a79d6c
1 parent 0507d73 commit 6237cfb

File tree

4 files changed

+19
-2
lines changed

4 files changed

+19
-2
lines changed

Libraries/Components/ScrollView/ScrollView.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -401,8 +401,8 @@ export type Props = $ReadOnly<{|
401401
/**
402402
* When true, the scroll view stops on the next index (in relation to scroll
403403
* position at release) regardless of how fast the gesture is. This can be
404-
* used for horizontal pagination when the page is less than the width of
405-
* the ScrollView. The default value is false.
404+
* used for pagination when the page is less than the width of the
405+
* horizontal ScrollView or the height of the vertical ScrollView. The default value is false.
406406
*/
407407
disableIntervalMomentum?: ?boolean,
408408
/**

React/Views/ScrollView/RCTScrollView.m

+2
Original file line numberDiff line numberDiff line change
@@ -738,6 +738,8 @@ - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoi
738738
if (isHorizontal) {
739739
// Use current scroll offset to determine the next index to snap to when momentum disabled
740740
targetContentOffsetAlongAxis = self.disableIntervalMomentum ? scrollView.contentOffset.x : targetContentOffset->x;
741+
} else {
742+
targetContentOffsetAlongAxis = self.disableIntervalMomentum ? scrollView.contentOffset.y : targetContentOffset->y;
741743
}
742744

743745
// Offset based on desired alignment

ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java

+9
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ public class ReactScrollView extends ScrollView
7373
private @Nullable String mScrollPerfTag;
7474
private @Nullable Drawable mEndBackground;
7575
private int mEndFillColor = Color.TRANSPARENT;
76+
private boolean mDisableIntervalMomentum = false;
7677
private int mSnapInterval = 0;
7778
private float mDecelerationRate = 0.985f;
7879
private @Nullable List<Integer> mSnapOffsets;
@@ -135,6 +136,10 @@ private OverScroller getOverScrollerFromParent() {
135136
return scroller;
136137
}
137138

139+
public void setDisableIntervalMomentum(boolean disableIntervalMomentum) {
140+
mDisableIntervalMomentum = disableIntervalMomentum;
141+
}
142+
138143
public void setSendMomentumEvents(boolean sendMomentumEvents) {
139144
mSendMomentumEvents = sendMomentumEvents;
140145
}
@@ -609,6 +614,10 @@ private void flingAndSnap(int velocityY) {
609614

610615
int maximumOffset = getMaxScrollY();
611616
int targetOffset = predictFinalScrollPosition(velocityY);
617+
if (mDisableIntervalMomentum) {
618+
targetOffset = getScrollY();
619+
}
620+
612621
int smallerOffset = 0;
613622
int largerOffset = maximumOffset;
614623
int firstOffset = 0;

ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java

+6
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,12 @@ public void setDecelerationRate(ReactScrollView view, float decelerationRate) {
8585
view.setDecelerationRate(decelerationRate);
8686
}
8787

88+
@ReactProp(name = "disableIntervalMomentum")
89+
public void setDisableIntervalMomentum(
90+
ReactScrollView view, boolean disbaleIntervalMomentum) {
91+
view.setDisableIntervalMomentum(disbaleIntervalMomentum);
92+
}
93+
8894
@ReactProp(name = "snapToInterval")
8995
public void setSnapToInterval(ReactScrollView view, float snapToInterval) {
9096
// snapToInterval needs to be exposed as a float because of the Javascript interface.

0 commit comments

Comments
 (0)