Skip to content

Commit

Permalink
Fixing RTL HorizontalScrolling in Android
Browse files Browse the repository at this point in the history
Reviewed By: astreet

Differential Revision: D6170631

fbshipit-source-id: 254e6ed9a4d6e42b6d1215de1ff63aedb2c07a0a
  • Loading branch information
mdvacca authored and facebook-github-bot committed Oct 27, 2017
1 parent e707891 commit c278020
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 1 deletion.
7 changes: 6 additions & 1 deletion Libraries/Components/ScrollView/ScrollView.js
Expand Up @@ -659,10 +659,11 @@ const ScrollView = createReactClass({
} else if (Platform.OS === 'android') {
if (this.props.horizontal) {
ScrollViewClass = AndroidHorizontalScrollView;
ScrollContentContainerViewClass = AndroidHorizontalScrollContentView;
} else {
ScrollViewClass = AndroidScrollView;
ScrollContentContainerViewClass = View;
}
ScrollContentContainerViewClass = View;
}

invariant(
Expand Down Expand Up @@ -880,6 +881,7 @@ const styles = StyleSheet.create({

let nativeOnlyProps,
AndroidScrollView,
AndroidHorizontalScrollContentView,
AndroidHorizontalScrollView,
RCTScrollView,
RCTScrollContentView;
Expand All @@ -899,6 +901,9 @@ if (Platform.OS === 'android') {
(ScrollView: React.ComponentType<any>),
nativeOnlyProps
);
AndroidHorizontalScrollContentView = requireNativeComponent(
'AndroidHorizontalScrollContentView'
);
} else if (Platform.OS === 'ios') {
nativeOnlyProps = {
nativeOnly: {
Expand Down
Expand Up @@ -61,6 +61,7 @@
import com.facebook.react.views.picker.ReactDialogPickerManager;
import com.facebook.react.views.picker.ReactDropdownPickerManager;
import com.facebook.react.views.progressbar.ReactProgressBarViewManager;
import com.facebook.react.views.scroll.ReactHorizontalScrollContainerViewManager;
import com.facebook.react.views.scroll.ReactHorizontalScrollViewManager;
import com.facebook.react.views.scroll.ReactScrollViewManager;
import com.facebook.react.views.slider.ReactSliderManager;
Expand Down Expand Up @@ -315,6 +316,7 @@ public List<ViewManager> createViewManagers(ReactApplicationContext reactContext
viewManagers.add(new ReactDrawerLayoutManager());
viewManagers.add(new ReactDropdownPickerManager());
viewManagers.add(new ReactHorizontalScrollViewManager());
viewManagers.add(new ReactHorizontalScrollContainerViewManager());
viewManagers.add(new ReactProgressBarViewManager());
viewManagers.add(new ReactScrollViewManager());
viewManagers.add(new ReactSliderManager());
Expand Down
Expand Up @@ -16,6 +16,7 @@ android_library(
react_native_target("java/com/facebook/react/bridge:bridge"),
react_native_target("java/com/facebook/react/common:common"),
react_native_target("java/com/facebook/react/module/annotations:annotations"),
react_native_target("java/com/facebook/react/modules/i18nmanager:i18nmanager"),
react_native_target("java/com/facebook/react/touch:touch"),
react_native_target("java/com/facebook/react/uimanager:uimanager"),
react_native_target("java/com/facebook/react/uimanager/annotations:annotations"),
Expand Down
@@ -0,0 +1,40 @@
// Copyright 2004-present Facebook. All Rights Reserved.

package com.facebook.react.views.scroll;

import android.content.Context;
import android.view.ViewGroup;
import android.widget.HorizontalScrollView;
import com.facebook.react.modules.i18nmanager.I18nUtil;

/** Container of Horizontal scrollViews that supports RTL scrolling. */
public class ReactHorizontalScrollContainerView extends ViewGroup {

private int mLayoutDirection;

public ReactHorizontalScrollContainerView(Context context) {
super(context);
mLayoutDirection =
I18nUtil.getInstance().isRTL(context) ? LAYOUT_DIRECTION_RTL : LAYOUT_DIRECTION_LTR;
}

@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
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
int newLeft = 0;
int width = right - left;
int newRight = newLeft + width;
setLeft(newLeft);
setRight(newRight);

// Fix the ScrollX position when using RTL language
int offsetX = computeHorizontalScrollRange() - getScrollX();

// Call with the present values in order to re-layout if necessary
HorizontalScrollView parent = (HorizontalScrollView) getParent();
parent.scrollTo(offsetX, parent.getScrollY());
}
}
}
@@ -0,0 +1,27 @@
// Copyright 2004-present Facebook. All Rights Reserved.

package com.facebook.react.views.scroll;

import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.ViewGroupManager;

/** View manager for {@link ReactHorizontalScrollContainerView} components. */
@ReactModule(name = ReactHorizontalScrollContainerViewManager.REACT_CLASS)
public class ReactHorizontalScrollContainerViewManager
extends ViewGroupManager<ReactHorizontalScrollContainerView> {

protected static final String REACT_CLASS = "AndroidHorizontalScrollContentView";

public ReactHorizontalScrollContainerViewManager() {}

@Override
public String getName() {
return REACT_CLASS;
}

@Override
public ReactHorizontalScrollContainerView createViewInstance(ThemedReactContext context) {
return new ReactHorizontalScrollContainerView(context);
}
}

0 comments on commit c278020

Please sign in to comment.