diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/common/ViewHelper.java b/ReactAndroid/src/main/java/com/facebook/react/views/common/ViewHelper.java index acbcefd6d..a560cafcb 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/common/ViewHelper.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/common/ViewHelper.java @@ -4,7 +4,6 @@ package com.facebook.react.views.common; import android.graphics.drawable.Drawable; import android.os.Build; -import android.support.annotation.Nullable; import android.view.View; /** Helper class for Views */ @@ -19,7 +18,7 @@ public class ViewHelper { * @param drawable {@link Drawable} The Drawable to use as the background, or null to remove the * background */ - public static void setBackground(View view, @Nullable Drawable drawable) { + public static void setBackground(View view, Drawable drawable) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { view.setBackground(drawable); } else { diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewBackgroundManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewBackgroundManager.java index 1076c9ba3..0248b93c6 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewBackgroundManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewBackgroundManager.java @@ -57,10 +57,6 @@ public class ReactViewBackgroundManager { getOrCreateReactViewBackground().setRadius(borderRadius); } - public boolean hasRoundedBorders() { - return getOrCreateReactViewBackground().hasRoundedBorders(); - } - public void setBorderRadius(float borderRadius, int position) { getOrCreateReactViewBackground().setRadius(borderRadius, position); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java b/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java index 3351c2845..e0984f86e 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewGroup.java @@ -35,7 +35,6 @@ import com.facebook.react.uimanager.ReactClippingViewGroupHelper; import com.facebook.react.uimanager.ReactPointerEventsView; import com.facebook.react.uimanager.ReactZIndexedViewGroup; import com.facebook.react.uimanager.ViewGroupDrawingOrderHelper; -import com.facebook.react.views.common.ViewHelper; import com.facebook.yoga.YogaConstants; import javax.annotation.Nullable; @@ -52,7 +51,6 @@ public class ReactViewGroup extends ViewGroup implements private static final LayoutParams sDefaultLayoutParam = new ViewGroup.LayoutParams(0, 0); /* should only be used in {@link #updateClippingToRect} */ private static final Rect sHelperRect = new Rect(); - private ReactViewBackgroundManager mReactBackgroundManager; /** * This listener will be set for child views when removeClippedSubview property is enabled. When @@ -113,7 +111,6 @@ public class ReactViewGroup extends ViewGroup implements public ReactViewGroup(Context context) { super(context); mDrawingOrderHelper = new ViewGroupDrawingOrderHelper(this); - mReactBackgroundManager = new ReactViewBackgroundManager(this); } @Override @@ -147,19 +144,17 @@ public class ReactViewGroup extends ViewGroup implements @Override public void setBackgroundColor(int color) { - mReactBackgroundManager.setBackgroundColor(color); + if (color == Color.TRANSPARENT && mReactBackgroundDrawable == null) { + // don't do anything, no need to allocate ReactBackgroundDrawable for transparent background + } else { + getOrCreateReactViewBackground().setColor(color); + } } - public void setBorderWidth(int position, float width) { - mReactBackgroundManager.setBorderWidth(position, width); - } - - public void setBorderColor(int position, float color, float alpha) { - mReactBackgroundManager.setBorderColor(position, color, alpha); - } - - public void setBorderStyle(@Nullable String style) { - mReactBackgroundManager.setBorderStyle(style); + @Override + public void setBackground(Drawable drawable) { + throw new UnsupportedOperationException( + "This method is not supported for ReactViewGroup instances"); } public void setTranslucentBackgroundDrawable(@Nullable Drawable background) { @@ -167,13 +162,13 @@ public class ReactViewGroup extends ViewGroup implements // background to be a layer drawable that contains a drawable that has been previously setup // as a background previously. This will not work correctly as the drawable callback logic is // messed up in AOSP - ViewHelper.setBackground(this, null); + updateBackgroundDrawable(null); if (mReactBackgroundDrawable != null && background != null) { LayerDrawable layerDrawable = new LayerDrawable(new Drawable[] {mReactBackgroundDrawable, background}); - ViewHelper.setBackground(this, layerDrawable); + updateBackgroundDrawable(layerDrawable); } else if (background != null) { - ViewHelper.setBackground(this, background); + updateBackgroundDrawable(background); } } @@ -225,13 +220,22 @@ public class ReactViewGroup extends ViewGroup implements mNeedsOffscreenAlphaCompositing = needsOffscreenAlphaCompositing; } + public void setBorderWidth(int position, float width) { + getOrCreateReactViewBackground().setBorderWidth(position, width); + } + + public void setBorderColor(int position, float rgb, float alpha) { + getOrCreateReactViewBackground().setBorderColor(position, rgb, alpha); + } + public void setBorderRadius(float borderRadius) { - mReactBackgroundManager.setBorderRadius(borderRadius); + ReactViewBackgroundDrawable backgroundDrawable = getOrCreateReactViewBackground(); + backgroundDrawable.setRadius(borderRadius); if (Build.VERSION_CODES.HONEYCOMB < Build.VERSION.SDK_INT && Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) { final int UPDATED_LAYER_TYPE = - mReactBackgroundManager.hasRoundedBorders() + backgroundDrawable.hasRoundedBorders() ? View.LAYER_TYPE_SOFTWARE : View.LAYER_TYPE_HARDWARE; @@ -242,12 +246,13 @@ public class ReactViewGroup extends ViewGroup implements } public void setBorderRadius(float borderRadius, int position) { - mReactBackgroundManager.setBorderRadius(borderRadius, position); + ReactViewBackgroundDrawable backgroundDrawable = getOrCreateReactViewBackground(); + backgroundDrawable.setRadius(borderRadius, position); if (Build.VERSION_CODES.HONEYCOMB < Build.VERSION.SDK_INT && Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR2) { final int UPDATED_LAYER_TYPE = - mReactBackgroundManager.hasRoundedBorders() + backgroundDrawable.hasRoundedBorders() ? View.LAYER_TYPE_SOFTWARE : View.LAYER_TYPE_HARDWARE; @@ -257,6 +262,10 @@ public class ReactViewGroup extends ViewGroup implements } } + public void setBorderStyle(@Nullable String style) { + getOrCreateReactViewBackground().setBorderStyle(style); + } + @Override public void setRemoveClippedSubviews(boolean removeClippedSubviews) { if (removeClippedSubviews == mRemoveClippedSubviews) { @@ -591,6 +600,32 @@ public class ReactViewGroup extends ViewGroup implements return DEFAULT_BACKGROUND_COLOR; } + private ReactViewBackgroundDrawable getOrCreateReactViewBackground() { + if (mReactBackgroundDrawable == null) { + mReactBackgroundDrawable = new ReactViewBackgroundDrawable(getContext()); + Drawable backgroundDrawable = getBackground(); + updateBackgroundDrawable( + null); // required so that drawable callback is cleared before we add the + // drawable back as a part of LayerDrawable + if (backgroundDrawable == null) { + updateBackgroundDrawable(mReactBackgroundDrawable); + } else { + LayerDrawable layerDrawable = + new LayerDrawable(new Drawable[] {mReactBackgroundDrawable, backgroundDrawable}); + updateBackgroundDrawable(layerDrawable); + } + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { + mLayoutDirection = + I18nUtil.getInstance().isRTL(getContext()) + ? LAYOUT_DIRECTION_RTL + : LAYOUT_DIRECTION_LTR; + mReactBackgroundDrawable.setResolvedLayoutDirection(mLayoutDirection); + } + } + return mReactBackgroundDrawable; + } + @Override public @Nullable Rect getHitSlopRect() { return mHitSlopRect; @@ -605,6 +640,21 @@ public class ReactViewGroup extends ViewGroup implements invalidate(); } + /** + * Set the background for the view or remove the background. It calls {@link + * #setBackground(Drawable)} or {@link #setBackgroundDrawable(Drawable)} based on the sdk version. + * + * @param drawable {@link Drawable} The Drawable to use as the background, or null to remove the + * background + */ + private void updateBackgroundDrawable(Drawable drawable) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + super.setBackground(drawable); + } else { + super.setBackgroundDrawable(drawable); + } + } + @Override protected void dispatchDraw(Canvas canvas) { if (mOverflow != null) {