mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
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
This commit is contained in:
committed by
Facebook GitHub Bot
parent
b8a2f34dee
commit
be260b9f47
@@ -254,8 +254,8 @@ public class ReactScrollView extends ScrollView
|
||||
@Override
|
||||
protected void onLayout(boolean changed, int l, int t, int r, int b) {
|
||||
// Call with the present values in order to re-layout if necessary
|
||||
// If a "pending" value has been set, we restore that value.
|
||||
// That value gets cleared by reactScrollTo.
|
||||
// If a "pending" content offset value has been set, we restore that value.
|
||||
// Upon call to scrollTo, the "pending" values will be re-set.
|
||||
int scrollToX =
|
||||
pendingContentOffsetX != UNSET_CONTENT_OFFSET ? pendingContentOffsetX : getScrollX();
|
||||
int scrollToY =
|
||||
@@ -954,23 +954,21 @@ public class ReactScrollView extends ScrollView
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls `reactScrollTo` and updates state.
|
||||
* Calls `updateFabricScrollState` and updates state.
|
||||
*
|
||||
* <p>`reactScrollTo` changes `contentOffset` and we need to keep `contentOffset` in sync between
|
||||
* scroll view and state. Calling raw `reactScrollTo` doesn't update state.
|
||||
*
|
||||
* <p>Note that while we can override scrollTo, we *cannot* override `smoothScrollTo` because it
|
||||
* is final. See `reactSmoothScrollTo`.
|
||||
* <p>`scrollTo` changes `contentOffset` and we need to keep `contentOffset` in sync between
|
||||
* scroll view and state. Calling ScrollView's `scrollTo` doesn't update state.
|
||||
*/
|
||||
@Override
|
||||
public void scrollTo(int x, int y) {
|
||||
super.scrollTo(x, y);
|
||||
// The final scroll position might be different from (x, y). For example, we may need to scroll
|
||||
// to the last item in the list, but that item cannot be move to the start position of the view.
|
||||
final int actualX = getScrollX();
|
||||
final int actualY = getScrollY();
|
||||
ReactScrollViewHelper.updateFabricScrollState(this, actualX, actualY);
|
||||
setPendingContentOffsets(actualX, actualY);
|
||||
ReactScrollViewHelper.updateFabricScrollState(this);
|
||||
setPendingContentOffsets(x, y);
|
||||
}
|
||||
|
||||
private boolean isContentReady() {
|
||||
View child = getChildAt(0);
|
||||
return child != null && child.getWidth() != 0 && child.getHeight() != 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -981,8 +979,7 @@ public class ReactScrollView extends ScrollView
|
||||
* @param y
|
||||
*/
|
||||
private void setPendingContentOffsets(int x, int y) {
|
||||
View child = getChildAt(0);
|
||||
if (child != null && child.getWidth() != 0 && child.getHeight() != 0) {
|
||||
if (isContentReady()) {
|
||||
pendingContentOffsetX = UNSET_CONTENT_OFFSET;
|
||||
pendingContentOffsetY = UNSET_CONTENT_OFFSET;
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user