Skip to content

Commit

Permalink
In onLayout, only scroll if the content view is ready
Browse files Browse the repository at this point in the history
Summary:
ScrollViews don't properly maintain position where they are hidden and shown. There is an edge case where on onLayout for a ScrollView, its content may not have been laid out yet. This happens in some cases when a scroll view is hidden via display: 'none' (resulting in setVisibility(INVISIBLE)). Check that the content view is laid out before attempting a scroll.

Changelog:
[Internal][Fixed] - In onLayout, only scroll if the content view is ready

Reviewed By: sshic

Differential Revision: D42794750

fbshipit-source-id: 654a380bcae306da2704d3e190423c8de125833d
  • Loading branch information
genkikondo authored and facebook-github-bot committed Jan 30, 2023
1 parent 47903d0 commit 9e65ba2
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -356,14 +356,17 @@ protected void onLayout(boolean changed, int l, int t, int r, int b) {
mScrollXAfterMeasure = NO_SCROLL_POSITION;
}

// 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.
int scrollToX =
pendingContentOffsetX != UNSET_CONTENT_OFFSET ? pendingContentOffsetX : getScrollX();
int scrollToY =
pendingContentOffsetY != UNSET_CONTENT_OFFSET ? pendingContentOffsetY : getScrollY();
scrollTo(scrollToX, scrollToY);
// Apply pending contentOffset in case it was set before the view was laid out.
if (isContentReady()) {
// 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 =
pendingContentOffsetY != UNSET_CONTENT_OFFSET ? pendingContentOffsetY : getScrollY();
scrollTo(scrollToX, scrollToY);
}

ReactScrollViewHelper.emitLayoutEvent(this);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -286,14 +286,17 @@ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {

@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" 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 =
pendingContentOffsetY != UNSET_CONTENT_OFFSET ? pendingContentOffsetY : getScrollY();
scrollTo(scrollToX, scrollToY);
// Apply pending contentOffset in case it was set before the view was laid out.
if (isContentReady()) {
// 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 =
pendingContentOffsetY != UNSET_CONTENT_OFFSET ? pendingContentOffsetY : getScrollY();
scrollTo(scrollToX, scrollToY);
}

ReactScrollViewHelper.emitLayoutEvent(this);
}

Expand Down

0 comments on commit 9e65ba2

Please sign in to comment.