Skip to content

Commit be260b9

Browse files
genkikondofacebook-github-bot
authored andcommitted
Fix ScrollView contentOffset
Summary: When setting ScrollView's contentOffset, if the ScrollView hasn't been laid out yet when ReactScrollViewManager.setContentOffset is called, then scroll position is never set properly. This is because the actual scroll offset (0, 0) was being passed into setPendingContentOffsets, instead of the desired scroll offset. Thus, when ReactScrollView.onLayout gets called, ReactScrollView.scrollTo gets called with (0, 0). Also updates out of date comments, Changelog: [Android][Fixed] - Fix ScrollView contentOffset Reviewed By: ryancat Differential Revision: D34015853 fbshipit-source-id: 84141a663fdb0ace2be7cef61f14944cb08125d1
1 parent b8a2f34 commit be260b9

File tree

1 file changed

+13
-16
lines changed

1 file changed

+13
-16
lines changed

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

+13-16
Original file line numberDiff line numberDiff line change
@@ -254,8 +254,8 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
254254
@Override
255255
protected void onLayout(boolean changed, int l, int t, int r, int b) {
256256
// Call with the present values in order to re-layout if necessary
257-
// If a "pending" value has been set, we restore that value.
258-
// That value gets cleared by reactScrollTo.
257+
// If a "pending" content offset value has been set, we restore that value.
258+
// Upon call to scrollTo, the "pending" values will be re-set.
259259
int scrollToX =
260260
pendingContentOffsetX != UNSET_CONTENT_OFFSET ? pendingContentOffsetX : getScrollX();
261261
int scrollToY =
@@ -954,23 +954,21 @@ public void reactSmoothScrollTo(int x, int y) {
954954
}
955955

956956
/**
957-
* Calls `reactScrollTo` and updates state.
957+
* Calls `updateFabricScrollState` and updates state.
958958
*
959-
* <p>`reactScrollTo` changes `contentOffset` and we need to keep `contentOffset` in sync between
960-
* scroll view and state. Calling raw `reactScrollTo` doesn't update state.
961-
*
962-
* <p>Note that while we can override scrollTo, we *cannot* override `smoothScrollTo` because it
963-
* is final. See `reactSmoothScrollTo`.
959+
* <p>`scrollTo` changes `contentOffset` and we need to keep `contentOffset` in sync between
960+
* scroll view and state. Calling ScrollView's `scrollTo` doesn't update state.
964961
*/
965962
@Override
966963
public void scrollTo(int x, int y) {
967964
super.scrollTo(x, y);
968-
// The final scroll position might be different from (x, y). For example, we may need to scroll
969-
// to the last item in the list, but that item cannot be move to the start position of the view.
970-
final int actualX = getScrollX();
971-
final int actualY = getScrollY();
972-
ReactScrollViewHelper.updateFabricScrollState(this, actualX, actualY);
973-
setPendingContentOffsets(actualX, actualY);
965+
ReactScrollViewHelper.updateFabricScrollState(this);
966+
setPendingContentOffsets(x, y);
967+
}
968+
969+
private boolean isContentReady() {
970+
View child = getChildAt(0);
971+
return child != null && child.getWidth() != 0 && child.getHeight() != 0;
974972
}
975973

976974
/**
@@ -981,8 +979,7 @@ public void scrollTo(int x, int y) {
981979
* @param y
982980
*/
983981
private void setPendingContentOffsets(int x, int y) {
984-
View child = getChildAt(0);
985-
if (child != null && child.getWidth() != 0 && child.getHeight() != 0) {
982+
if (isContentReady()) {
986983
pendingContentOffsetX = UNSET_CONTENT_OFFSET;
987984
pendingContentOffsetY = UNSET_CONTENT_OFFSET;
988985
} else {

0 commit comments

Comments
 (0)