Skip to content

Commit

Permalink
Fix RTL content jumping
Browse files Browse the repository at this point in the history
Summary:
Whenever layout updates in a horizontal scrollview, in RTL mode we adjust the position - the impact *should* be that initially, we jump from position 0 to the right side of the scroll view,
such that scrolling starts from the right.

However, we were doing this entirely too aggressively before. We should only make this adjustment *if the layout changes the width*.

Changelog: [Android][Changed] Fixed jumpy RTL horizontal ScrollViews. If you have Android-specific JS hacks for handling RTL in ScrollViews, you probably can/probably want to remove them, because they should be reliable now and require fewer hacks.

Reviewed By: mdvacca

Differential Revision: D26771366

fbshipit-source-id: de11bd1cae1414018d88ce44b3583a8b15f3b330
  • Loading branch information
JoshuaGross authored and facebook-github-bot committed Mar 6, 2021
1 parent 00959ff commit fc032cd
Showing 1 changed file with 14 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,6 @@ public void setRemoveClippedSubviews(boolean removeClippedSubviews) {

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
/**
* Note: in RTL mode, *when layout width changes*, we adjust the scroll position. Practically,
* this means that on the first (meaningful) layout we will go from position 0 to position
* (right - screenWidth). In theory this means if the width of the view ever changes during
* layout again, scrolling could jump. Which shouldn't happen in theory, but... if you find a
* weird product bug that looks related, keep this in mind.
*/
if (mLayoutDirection == LAYOUT_DIRECTION_RTL) {
// When the layout direction is RTL, we expect Yoga to give us a layout
// that extends off the screen to the left so we re-center it with left=0
Expand All @@ -60,11 +53,20 @@ protected void onLayout(boolean changed, int left, int top, int right, int botto
setLeft(newLeft);
setRight(newRight);

// Call with the present values in order to re-layout if necessary
ReactHorizontalScrollView parent = (ReactHorizontalScrollView) getParent();
// Fix the ScrollX position when using RTL language
int offsetX = parent.getScrollX() + getWidth() - mCurrentWidth;
parent.reactScrollTo(offsetX, parent.getScrollY());
/**
* Note: in RTL mode, *when layout width changes*, we adjust the scroll position. Practically,
* this means that on the first (meaningful) layout we will go from position 0 to position
* (right - screenWidth). In theory this means if the width of the view ever changes during
* layout again, scrolling could jump. Which shouldn't happen in theory, but... if you find a
* weird product bug that looks related, keep this in mind.
*/
if (mCurrentWidth != getWidth()) {
// Call with the present values in order to re-layout if necessary
ReactHorizontalScrollView parent = (ReactHorizontalScrollView) getParent();
// Fix the ScrollX position when using RTL language
int offsetX = parent.getScrollX() + getWidth() - mCurrentWidth;
parent.reactScrollTo(offsetX, parent.getScrollY());
}
}
mCurrentWidth = getWidth();
}
Expand Down

0 comments on commit fc032cd

Please sign in to comment.