mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Implement snapToAlignment in vertical ScrollView
Summary: This diff implements the SnapToAlignment functionality in ReactScrollView for RN Android. In order to use SnapToAlignment, the pagingEnabled prop should be set Based on the documentation the behavior implemented in this diff is more "advanced" than the one implemendted in RNiOS, because it let you snap without specifying any interval nor offset (it calculates the intervals in real time based on the size of its content) I still need to verify how different RNiOS and RN Android behaviors are changelog: [Android][Added] Implement SnapToAlignment in ReactScrollView Reviewed By: JoshuaGross Differential Revision: D31182786 fbshipit-source-id: a9b55d9c00326ae21ca9b89575e79c60bf9edcca
This commit is contained in:
committed by
Facebook GitHub Bot
parent
c6e5640e87
commit
e774c037bc
+1
-1
@@ -975,7 +975,7 @@ public class ReactHorizontalScrollView extends HorizontalScrollView
|
||||
itemStartOffset = item.getLeft() - (width - item.getWidth());
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("");
|
||||
throw new IllegalStateException("Invalid SnapToAlignment value: " + mSnapToAlignment);
|
||||
}
|
||||
if (itemStartOffset <= targetOffset) {
|
||||
if (targetOffset - itemStartOffset < targetOffset - smallerOffset) {
|
||||
|
||||
@@ -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;
|
||||
@@ -641,6 +644,10 @@ public class ReactScrollView extends ScrollView
|
||||
return scroller.getFinalY();
|
||||
}
|
||||
|
||||
private View getContentView() {
|
||||
return getChildAt(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* This will smooth scroll us to the nearest snap offset point It currently just looks at where
|
||||
* the content is and slides to the nearest point. It is intended to be run after we are done
|
||||
@@ -697,7 +704,7 @@ public class ReactScrollView extends ScrollView
|
||||
}
|
||||
|
||||
// pagingEnabled only allows snapping one interval at a time
|
||||
if (mSnapInterval == 0 && mSnapOffsets == null) {
|
||||
if (mSnapInterval == 0 && mSnapOffsets == null && mSnapToAlignment == SNAP_ALIGNMENT_DISABLED) {
|
||||
smoothScrollAndSnap(velocityY);
|
||||
return;
|
||||
}
|
||||
@@ -734,6 +741,37 @@ public class ReactScrollView extends ScrollView
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} 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.getTop() - (height - item.getHeight()) / 2;
|
||||
break;
|
||||
case SNAP_ALIGNMENT_START:
|
||||
itemStartOffset = item.getTop();
|
||||
break;
|
||||
case SNAP_ALIGNMENT_END:
|
||||
itemStartOffset = item.getTop() - (height - item.getHeight());
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Invalid SnapToAlignment value: " + mSnapToAlignment);
|
||||
}
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user