Skip to content

Commit ddd65f1

Browse files
Jimmy Zhuangfacebook-github-bot
Jimmy Zhuang
authored andcommitted
Support snapToInterval for horizontal scrollview on Android
Summary: `snapToInterval` is available on iOS but on android yet. This PR is to add support for `snapToInterval` on android. Example: ![android_snap](https://cloud.githubusercontent.com/assets/1699429/19086983/39d3ee1c-8a25-11e6-9c84-20f25a751f32.gif) TO: lelandrichardson spikebrehm Closes #10242 Differential Revision: D4168527 fbshipit-source-id: de3dd9ac5d9e0fddfce5e5bc0aa6a4f33f1e30b3
1 parent a8391bd commit ddd65f1

File tree

4 files changed

+42
-5
lines changed

4 files changed

+42
-5
lines changed

Libraries/Components/ScrollView/ScrollView.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -344,10 +344,10 @@ const ScrollView = createReactClass({
344344
* When set, causes the scroll view to stop at multiples of the value of
345345
* `snapToInterval`. This can be used for paginating through children
346346
* that have lengths smaller than the scroll view. Typically used in
347-
* combination with `snapToAlignment` and `decelerationRate="fast"`.
347+
* combination with `snapToAlignment` and `decelerationRate="fast"` on ios.
348348
* Overrides less configurable `pagingEnabled` prop.
349349
*
350-
* @platform ios
350+
* Supported for horizontal scrollview on android.
351351
*/
352352
snapToInterval: PropTypes.number,
353353
/**

RNTester/js/ScrollViewSimpleExample.js

+18-1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,20 @@ class ScrollViewSimpleExample extends React.Component<{}> {
4646
{this.makeItems(NUM_ITEMS, [styles.itemWrapper, styles.horizontalItemWrapper])}
4747
</ScrollView>
4848
);
49+
items.push(
50+
<ScrollView
51+
key={'scrollViewSnap'}
52+
horizontal
53+
snapToInterval={210}
54+
pagingEnabled
55+
>
56+
{this.makeItems(NUM_ITEMS, [
57+
styles.itemWrapper,
58+
styles.horizontalItemWrapper,
59+
styles.horizontalPagingItemWrapper,
60+
])}
61+
</ScrollView>
62+
);
4963

5064
var verticalScrollView = (
5165
<ScrollView style={styles.verticalScrollView}>
@@ -72,7 +86,10 @@ var styles = StyleSheet.create({
7286
},
7387
horizontalItemWrapper: {
7488
padding: 50
75-
}
89+
},
90+
horizontalPagingItemWrapper: {
91+
width: 200,
92+
},
7693
});
7794

7895
module.exports = ScrollViewSimpleExample;

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

+14-2
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ public class ReactHorizontalScrollView extends HorizontalScrollView implements
4848
private @Nullable String mScrollPerfTag;
4949
private @Nullable Drawable mEndBackground;
5050
private int mEndFillColor = Color.TRANSPARENT;
51+
private int mSnapInterval = 0;
5152
private ReactViewBackgroundManager mReactBackgroundManager;
5253

5354
public ReactHorizontalScrollView(Context context) {
@@ -90,6 +91,10 @@ public void setPagingEnabled(boolean pagingEnabled) {
9091
mPagingEnabled = pagingEnabled;
9192
}
9293

94+
public void setSnapInterval(int snapInterval) {
95+
mSnapInterval = snapInterval;
96+
}
97+
9398
public void flashScrollIndicators() {
9499
awakenScrollBars();
95100
}
@@ -114,7 +119,7 @@ protected void onScrollChanged(int x, int y, int oldX, int oldY) {
114119
super.onScrollChanged(x, y, oldX, oldY);
115120

116121
mActivelyScrolling = true;
117-
122+
118123
if (mOnScrollDispatchHelper.onScrollChanged(x, y)) {
119124
if (mRemoveClippedSubviews) {
120125
updateClippingRect();
@@ -212,6 +217,13 @@ public void getClippingRect(Rect outClippingRect) {
212217
outClippingRect.set(Assertions.assertNotNull(mClippingRect));
213218
}
214219

220+
private int getSnapInterval() {
221+
if (mSnapInterval != 0) {
222+
return mSnapInterval;
223+
}
224+
return getWidth();
225+
}
226+
215227
public void setEndFillColor(int color) {
216228
if (color != mEndFillColor) {
217229
mEndFillColor = color;
@@ -312,7 +324,7 @@ public void run() {
312324
* scrolling.
313325
*/
314326
private void smoothScrollToPage(int velocity) {
315-
int width = getWidth();
327+
int width = getSnapInterval();
316328
int currentX = getScrollX();
317329
// TODO (t11123799) - Should we do anything beyond linear accounting of the velocity
318330
int predictedX = currentX + velocity;

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

+8
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@
1010
package com.facebook.react.views.scroll;
1111

1212
import android.graphics.Color;
13+
import android.util.DisplayMetrics;
1314
import com.facebook.react.bridge.ReadableArray;
1415
import com.facebook.react.module.annotations.ReactModule;
16+
import com.facebook.react.uimanager.DisplayMetricsHolder;
1517
import com.facebook.react.uimanager.PixelUtil;
1618
import com.facebook.react.uimanager.ReactClippingViewGroupHelper;
1719
import com.facebook.react.uimanager.Spacing;
@@ -70,6 +72,12 @@ public void setShowsHorizontalScrollIndicator(ReactHorizontalScrollView view, bo
7072
view.setHorizontalScrollBarEnabled(value);
7173
}
7274

75+
@ReactProp(name = "snapToInterval")
76+
public void setSnapToInterval(ReactHorizontalScrollView view, int snapToInterval) {
77+
DisplayMetrics screenDisplayMetrics = DisplayMetricsHolder.getScreenDisplayMetrics();
78+
view.setSnapInterval((int)(snapToInterval * screenDisplayMetrics.density));
79+
}
80+
7381
@ReactProp(name = ReactClippingViewGroupHelper.PROP_REMOVE_CLIPPED_SUBVIEWS)
7482
public void setRemoveClippedSubviews(ReactHorizontalScrollView view, boolean removeClippedSubviews) {
7583
view.setRemoveClippedSubviews(removeClippedSubviews);

0 commit comments

Comments
 (0)