Skip to content

Commit

Permalink
Support snapToInterval for horizontal scroll view on android
Browse files Browse the repository at this point in the history
  • Loading branch information
Jimmy Zhuang committed Nov 5, 2016
1 parent 1ceb2f7 commit 0c44323
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 5 deletions.
19 changes: 18 additions & 1 deletion Examples/UIExplorer/js/ScrollViewSimpleExample.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,20 @@ class ScrollViewSimpleExample extends React.Component {
{this.makeItems(NUM_ITEMS, [styles.itemWrapper, styles.horizontalItemWrapper])}
</ScrollView>
);
items.push(
<ScrollView
key={'scrollViewSnap'}
horizontal
snapToInterval={210}
pagingEnabled
>
{this.makeItems(NUM_ITEMS, [
styles.itemWrapper,
styles.horizontalItemWrapper,
styles.horizontalPagingItemWrapper,
])}
</ScrollView>
);

var verticalScrollView = (
<ScrollView style={styles.verticalScrollView}>
Expand All @@ -83,7 +97,10 @@ var styles = StyleSheet.create({
},
horizontalItemWrapper: {
padding: 50
}
},
horizontalPagingItemWrapper: {
width: 200,
},
});

module.exports = ScrollViewSimpleExample;
4 changes: 2 additions & 2 deletions Libraries/Components/ScrollView/ScrollView.js
Original file line number Diff line number Diff line change
Expand Up @@ -273,8 +273,8 @@ const ScrollView = React.createClass({
* When set, causes the scroll view to stop at multiples of the value of
* `snapToInterval`. This can be used for paginating through children
* that have lengths smaller than the scroll view. Used in combination
* with `snapToAlignment`.
* @platform ios
* with `snapToAlignment` on ios.
* Supported for horizontal scrollview on android. Use in combination with `pagingEnabled`.
*/
snapToInterval: PropTypes.number,
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public class ReactHorizontalScrollView extends HorizontalScrollView implements
private @Nullable String mScrollPerfTag;
private @Nullable Drawable mEndBackground;
private int mEndFillColor = Color.TRANSPARENT;
private int mSnapInterval = 0;

public ReactHorizontalScrollView(Context context) {
this(context, null);
Expand Down Expand Up @@ -88,6 +89,8 @@ public void setPagingEnabled(boolean pagingEnabled) {
mPagingEnabled = pagingEnabled;
}

public void setSnapInterval(int snapInterval) { mSnapInterval = snapInterval; }

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
MeasureSpecAssertions.assertExplicitMeasureSpec(widthMeasureSpec, heightMeasureSpec);
Expand Down Expand Up @@ -295,14 +298,21 @@ public void run() {
postOnAnimationDelayed(mPostTouchRunnable, ReactScrollViewHelper.MOMENTUM_DELAY);
}

private int getSnapInterval() {
if (mSnapInterval != 0) {
return mSnapInterval;
}
return getWidth();
}

/**
* This will smooth scroll us to the nearest page boundary
* It currently just looks at where the content is relative to the page and slides to the nearest
* page. It is intended to be run after we are done scrolling, and handling any momentum
* scrolling.
*/
private void smoothScrollToPage(int velocity) {
int width = getWidth();
int width = getSnapInterval();
int currentX = getScrollX();
// TODO (t11123799) - Should we do anything beyond linear accounting of the velocity
int predictedX = currentX + velocity;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@
import javax.annotation.Nullable;

import android.graphics.Color;
import android.util.DisplayMetrics;

import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.uimanager.DisplayMetricsHolder;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.ViewGroupManager;
Expand Down Expand Up @@ -58,6 +59,12 @@ public void setScrollEnabled(ReactHorizontalScrollView view, boolean value) {
view.setScrollEnabled(value);
}

@ReactProp(name = "snapToInterval")
public void setSnapToInterval(ReactHorizontalScrollView view, int snapToInterval) {
DisplayMetrics screenDisplayMetrics = DisplayMetricsHolder.getScreenDisplayMetrics();
view.setSnapInterval((int)(snapToInterval * screenDisplayMetrics.density));
}

@ReactProp(name = "showsHorizontalScrollIndicator")
public void setShowsHorizontalScrollIndicator(ReactHorizontalScrollView view, boolean value) {
view.setHorizontalScrollBarEnabled(value);
Expand Down

0 comments on commit 0c44323

Please sign in to comment.