diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java index 4ad2aede460501..5d52faf18130de 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java @@ -7,7 +7,10 @@ package com.facebook.react.views.scroll; +import static com.facebook.react.views.scroll.ReactScrollViewHelper.SNAP_ALIGNMENT_CENTER; import static com.facebook.react.views.scroll.ReactScrollViewHelper.SNAP_ALIGNMENT_DISABLED; +import static com.facebook.react.views.scroll.ReactScrollViewHelper.SNAP_ALIGNMENT_END; +import static com.facebook.react.views.scroll.ReactScrollViewHelper.SNAP_ALIGNMENT_START; import android.animation.Animator; import android.animation.ObjectAnimator; @@ -23,6 +26,7 @@ import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; +import android.view.ViewGroup; import android.view.accessibility.AccessibilityEvent; import android.widget.HorizontalScrollView; import android.widget.OverScroller; @@ -912,7 +916,7 @@ private void flingAndSnap(int velocityX) { } // pagingEnabled only allows snapping one interval at a time - if (mSnapInterval == 0 && mSnapOffsets == null) { + if (mSnapInterval == 0 && mSnapOffsets == null && mSnapToAlignment == SNAP_ALIGNMENT_DISABLED) { smoothScrollAndSnap(velocityX); return; } @@ -955,6 +959,36 @@ private void flingAndSnap(int velocityX) { } } } + } else if (mSnapToAlignment != SNAP_ALIGNMENT_DISABLED) { + ViewGroup contentView = (ViewGroup) getContentView(); + for (int i = 1; i < contentView.getChildCount(); i++) { + View item = contentView.getChildAt(i); + int itemStartOffset; + switch (mSnapToAlignment) { + case SNAP_ALIGNMENT_CENTER: + itemStartOffset = item.getLeft() - (width - item.getWidth()) / 2; + break; + case SNAP_ALIGNMENT_START: + itemStartOffset = item.getLeft(); + break; + case SNAP_ALIGNMENT_END: + itemStartOffset = item.getLeft() - (width - item.getWidth()); + break; + default: + throw new IllegalStateException(""); + } + if (itemStartOffset <= targetOffset) { + if (targetOffset - itemStartOffset < targetOffset - smallerOffset) { + smallerOffset = itemStartOffset; + } + } + + if (itemStartOffset >= targetOffset) { + if (itemStartOffset - targetOffset < largerOffset - targetOffset) { + largerOffset = itemStartOffset; + } + } + } } else { double interval = (double) getSnapInterval(); double ratio = (double) targetOffset / interval; diff --git a/packages/rn-tester/js/examples/ScrollView/ScrollViewSimpleExample.js b/packages/rn-tester/js/examples/ScrollView/ScrollViewSimpleExample.js index b4960f93ee4b15..312a4c42e53652 100644 --- a/packages/rn-tester/js/examples/ScrollView/ScrollViewSimpleExample.js +++ b/packages/rn-tester/js/examples/ScrollView/ScrollViewSimpleExample.js @@ -61,6 +61,45 @@ class ScrollViewSimpleExample extends React.Component<{...}> { ])} , ); + items.push( + + {this.makeItems(NUM_ITEMS, [ + styles.itemWrapper, + styles.horizontalItemWrapper, + styles.horizontalPagingItemWrapper, + ])} + , + ); + items.push( + + {this.makeItems(NUM_ITEMS, [ + styles.itemWrapper, + styles.horizontalItemWrapper, + styles.horizontalPagingItemWrapper, + ])} + , + ); + items.push( + + {this.makeItems(NUM_ITEMS, [ + styles.itemWrapper, + styles.horizontalItemWrapper, + styles.horizontalPagingItemWrapper, + ])} + , + ); const verticalScrollView = ( {items}