mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Extend ScrollView.snapToAlignments in RN Android to reach feature parity with RN iOS
Summary: This diff extends the current implementation of ScrollView.snapToAlignments from RN Android to reach feature parity with RNiOS changelog: [Android][Changed] Implement ScrollView.snapToAlignments in RN Android Reviewed By: javache Differential Revision: D31206398 fbshipit-source-id: b6534965c476a0a4745ac98b419cbe05dc5c746e
This commit is contained in:
committed by
Facebook GitHub Bot
parent
e774c037bc
commit
04184ef851
+52
-25
@@ -960,37 +960,45 @@ public class ReactHorizontalScrollView extends HorizontalScrollView
|
||||
}
|
||||
}
|
||||
} 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("Invalid SnapToAlignment value: " + mSnapToAlignment);
|
||||
}
|
||||
if (itemStartOffset <= targetOffset) {
|
||||
if (targetOffset - itemStartOffset < targetOffset - smallerOffset) {
|
||||
smallerOffset = itemStartOffset;
|
||||
if (mSnapInterval > 0) {
|
||||
double ratio = (double) targetOffset / mSnapInterval;
|
||||
smallerOffset =
|
||||
Math.max(
|
||||
getItemStartOffset(
|
||||
mSnapToAlignment,
|
||||
(int) (Math.floor(ratio) * mSnapInterval),
|
||||
mSnapInterval,
|
||||
width),
|
||||
0);
|
||||
largerOffset =
|
||||
Math.min(
|
||||
getItemStartOffset(
|
||||
mSnapToAlignment,
|
||||
(int) (Math.ceil(ratio) * mSnapInterval),
|
||||
mSnapInterval,
|
||||
width),
|
||||
maximumOffset);
|
||||
} else {
|
||||
ViewGroup contentView = (ViewGroup) getContentView();
|
||||
for (int i = 1; i < contentView.getChildCount(); i++) {
|
||||
View item = contentView.getChildAt(i);
|
||||
int itemStartOffset =
|
||||
getItemStartOffset(mSnapToAlignment, item.getLeft(), item.getWidth(), width);
|
||||
if (itemStartOffset <= targetOffset) {
|
||||
if (targetOffset - itemStartOffset < targetOffset - smallerOffset) {
|
||||
smallerOffset = itemStartOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (itemStartOffset >= targetOffset) {
|
||||
if (itemStartOffset - targetOffset < largerOffset - targetOffset) {
|
||||
largerOffset = itemStartOffset;
|
||||
if (itemStartOffset >= targetOffset) {
|
||||
if (itemStartOffset - targetOffset < largerOffset - targetOffset) {
|
||||
largerOffset = itemStartOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
double interval = (double) getSnapInterval();
|
||||
double interval = getSnapInterval();
|
||||
double ratio = (double) targetOffset / interval;
|
||||
smallerOffset = (int) (Math.floor(ratio) * interval);
|
||||
largerOffset = Math.min((int) (Math.ceil(ratio) * interval), maximumOffset);
|
||||
@@ -1073,6 +1081,25 @@ public class ReactHorizontalScrollView extends HorizontalScrollView
|
||||
}
|
||||
}
|
||||
|
||||
private int getItemStartOffset(
|
||||
int snapToAlignment, int itemStartPosition, int itemWidth, int viewPortWidth) {
|
||||
int itemStartOffset;
|
||||
switch (snapToAlignment) {
|
||||
case SNAP_ALIGNMENT_CENTER:
|
||||
itemStartOffset = itemStartPosition - (viewPortWidth - itemWidth) / 2;
|
||||
break;
|
||||
case SNAP_ALIGNMENT_START:
|
||||
itemStartOffset = itemStartPosition;
|
||||
break;
|
||||
case SNAP_ALIGNMENT_END:
|
||||
itemStartOffset = itemStartPosition - (viewPortWidth - itemWidth);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Invalid SnapToAlignment value: " + mSnapToAlignment);
|
||||
}
|
||||
return itemStartOffset;
|
||||
}
|
||||
|
||||
private void smoothScrollToNextPage(int direction) {
|
||||
if (DEBUG_MODE) {
|
||||
FLog.i(TAG, "smoothScrollToNextPage[%d] direction %d", getId(), direction);
|
||||
|
||||
@@ -743,32 +743,52 @@ 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 (mSnapInterval > 0) {
|
||||
double ratio = (double) targetOffset / mSnapInterval;
|
||||
smallerOffset =
|
||||
Math.max(
|
||||
getItemStartOffset(
|
||||
mSnapToAlignment,
|
||||
(int) (Math.floor(ratio) * mSnapInterval),
|
||||
mSnapInterval,
|
||||
height),
|
||||
0);
|
||||
largerOffset =
|
||||
Math.min(
|
||||
getItemStartOffset(
|
||||
mSnapToAlignment,
|
||||
(int) (Math.ceil(ratio) * mSnapInterval),
|
||||
mSnapInterval,
|
||||
height),
|
||||
maximumOffset);
|
||||
} else {
|
||||
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;
|
||||
if (itemStartOffset >= targetOffset) {
|
||||
if (itemStartOffset - targetOffset < largerOffset - targetOffset) {
|
||||
largerOffset = itemStartOffset;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -847,6 +867,25 @@ public class ReactScrollView extends ScrollView
|
||||
}
|
||||
}
|
||||
|
||||
private int getItemStartOffset(
|
||||
int snapToAlignment, int itemStartPosition, int itemHeight, int viewPortHeight) {
|
||||
int itemStartOffset;
|
||||
switch (snapToAlignment) {
|
||||
case SNAP_ALIGNMENT_CENTER:
|
||||
itemStartOffset = itemStartPosition - (viewPortHeight - itemHeight) / 2;
|
||||
break;
|
||||
case SNAP_ALIGNMENT_START:
|
||||
itemStartOffset = itemStartPosition;
|
||||
break;
|
||||
case SNAP_ALIGNMENT_END:
|
||||
itemStartOffset = itemStartPosition - (viewPortHeight - itemHeight);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalStateException("Invalid SnapToAlignment value: " + mSnapToAlignment);
|
||||
}
|
||||
return itemStartOffset;
|
||||
}
|
||||
|
||||
private int getSnapInterval() {
|
||||
if (mSnapInterval != 0) {
|
||||
return mSnapInterval;
|
||||
|
||||
Reference in New Issue
Block a user