diff --git a/Libraries/Components/ScrollView/ScrollView.js b/Libraries/Components/ScrollView/ScrollView.js index 8bedfbe26..37f522af6 100644 --- a/Libraries/Components/ScrollView/ScrollView.js +++ b/Libraries/Components/ScrollView/ScrollView.js @@ -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( @@ -880,6 +881,7 @@ const styles = StyleSheet.create({ let nativeOnlyProps, AndroidScrollView, + AndroidHorizontalScrollContentView, AndroidHorizontalScrollView, RCTScrollView, RCTScrollContentView; @@ -899,6 +901,9 @@ if (Platform.OS === 'android') { (ScrollView: React.ComponentType), nativeOnlyProps ); + AndroidHorizontalScrollContentView = requireNativeComponent( + 'AndroidHorizontalScrollContentView' + ); } else if (Platform.OS === 'ios') { nativeOnlyProps = { nativeOnly: { diff --git a/ReactAndroid/src/main/java/com/facebook/react/shell/MainReactPackage.java b/ReactAndroid/src/main/java/com/facebook/react/shell/MainReactPackage.java index a37e42edd..7605e21f9 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/shell/MainReactPackage.java +++ b/ReactAndroid/src/main/java/com/facebook/react/shell/MainReactPackage.java @@ -61,6 +61,7 @@ import com.facebook.react.views.modal.ReactModalHostManager; 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; @@ -315,6 +316,7 @@ public class MainReactPackage extends LazyReactPackage { 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()); diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/BUCK b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/BUCK index 0232e55f8..e1e594d6b 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/BUCK @@ -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"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollContainerView.java b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollContainerView.java new file mode 100644 index 000000000..3586fbcba --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollContainerView.java @@ -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()); + } + } +} diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollContainerViewManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollContainerViewManager.java new file mode 100644 index 000000000..f84f72aa5 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollContainerViewManager.java @@ -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 { + + 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); + } +}