Permalink
Browse files

Android: Implement border(Start|End)Width for non-rounded borders

Reviewed By: achen1

Differential Revision: D5917755

fbshipit-source-id: 3ec0ab1a1e191f5f6fd956691995e95937a513cc
  • Loading branch information...
RSNara authored and facebook-github-bot committed Oct 19, 2017
1 parent 04a8c62 commit 7ed7593b2b46496e8f58d21416888e0e05a4ce1e
@@ -624,18 +624,24 @@ public void setPaddings(int index, Dynamic padding) {
padding.recycle();
}
@ReactPropGroup(names = {
@ReactPropGroup(
names = {
ViewProps.BORDER_WIDTH,
ViewProps.BORDER_LEFT_WIDTH,
ViewProps.BORDER_RIGHT_WIDTH,
ViewProps.BORDER_START_WIDTH,
ViewProps.BORDER_END_WIDTH,
ViewProps.BORDER_TOP_WIDTH,
ViewProps.BORDER_BOTTOM_WIDTH,
}, defaultFloat = YogaConstants.UNDEFINED)
ViewProps.BORDER_LEFT_WIDTH,
ViewProps.BORDER_RIGHT_WIDTH,
},
defaultFloat = YogaConstants.UNDEFINED
)
public void setBorderWidths(int index, float borderWidth) {
if (isVirtual()) {
return;
}
setBorder(ViewProps.BORDER_SPACING_TYPES[index], PixelUtil.toPixelFromDIP(borderWidth));
int spacingType = maybeTransformLeftRightToStartEnd(ViewProps.BORDER_SPACING_TYPES[index]);
setBorder(spacingType, PixelUtil.toPixelFromDIP(borderWidth));
}
@ReactPropGroup(
@@ -103,6 +103,8 @@
public static final String BORDER_WIDTH = "borderWidth";
public static final String BORDER_LEFT_WIDTH = "borderLeftWidth";
public static final String BORDER_START_WIDTH = "borderStartWidth";
public static final String BORDER_END_WIDTH = "borderEndWidth";
public static final String BORDER_TOP_WIDTH = "borderTopWidth";
public static final String BORDER_RIGHT_WIDTH = "borderRightWidth";
public static final String BORDER_BOTTOM_WIDTH = "borderBottomWidth";
@@ -117,7 +119,13 @@
public static final String BORDER_TOP_COLOR = "borderTopColor";
public static final String BORDER_BOTTOM_COLOR = "borderBottomColor";
public static final int[] BORDER_SPACING_TYPES = {
Spacing.ALL, Spacing.START, Spacing.END, Spacing.TOP, Spacing.BOTTOM
Spacing.ALL,
Spacing.START,
Spacing.END,
Spacing.TOP,
Spacing.BOTTOM,
Spacing.LEFT,
Spacing.RIGHT
};
public static final int[] PADDING_MARGIN_SPACING_TYPES = {
Spacing.ALL,
@@ -16,6 +16,7 @@ android_library(
react_native_target("java/com/facebook/react/touch:touch"),
react_native_target("java/com/facebook/react/views/common:common"),
react_native_target("java/com/facebook/react/uimanager:uimanager"),
react_native_target("java/com/facebook/react/modules/i18nmanager:i18nmanager"),
react_native_target("java/com/facebook/react/uimanager/annotations:annotations"),
],
)
@@ -9,6 +9,7 @@
package com.facebook.react.views.view;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
@@ -23,7 +24,9 @@
import android.graphics.Region;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.view.View;
import com.facebook.react.common.annotations.VisibleForTesting;
import com.facebook.react.modules.i18nmanager.I18nUtil;
import com.facebook.react.uimanager.FloatUtil;
import com.facebook.react.uimanager.Spacing;
import com.facebook.yoga.YogaConstants;
@@ -105,6 +108,7 @@
private int mAlpha = 255;
private @Nullable float[] mBorderCornerRadii;
private final Context mContext;
public enum BorderRadiusLocation {
TOP_LEFT,
@@ -113,6 +117,10 @@
BOTTOM_LEFT
}
public ReactViewBackgroundDrawable(Context context) {
mContext = context;
}
@Override
public void draw(Canvas canvas) {
updatePathEffect();
@@ -810,9 +818,14 @@ private void drawRectangularBackgroundWithBorders(Canvas canvas) {
mPaint.setStyle(Paint.Style.FILL);
canvas.drawRect(getBounds(), mPaint);
}
// maybe draw borders?
if (getBorderWidth(Spacing.LEFT) > 0 || getBorderWidth(Spacing.TOP) > 0 ||
getBorderWidth(Spacing.RIGHT) > 0 || getBorderWidth(Spacing.BOTTOM) > 0) {
if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& (getBorderWidth(Spacing.START) > 0 || getBorderWidth(Spacing.END) > 0))
|| getBorderWidth(Spacing.LEFT) > 0
|| getBorderWidth(Spacing.TOP) > 0
|| getBorderWidth(Spacing.RIGHT) > 0
|| getBorderWidth(Spacing.BOTTOM) > 0) {
Rect bounds = getBounds();
int borderLeft = getBorderWidth(Spacing.LEFT);
@@ -824,6 +837,39 @@ private void drawRectangularBackgroundWithBorders(Canvas canvas) {
int colorRight = getBorderColor(Spacing.RIGHT);
int colorBottom = getBorderColor(Spacing.BOTTOM);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
final boolean isRTL = getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
int borderStart = getBorderWidth(Spacing.START);
int borderEnd = getBorderWidth(Spacing.END);
if (I18nUtil.getInstance().doesRTLFlipLeftAndRightStyles(mContext)) {
if (borderStart < 0) {
borderStart = borderLeft;
}
if (borderEnd < 0) {
borderEnd = borderRight;
}
final int directionAwareBorderLeft = isRTL ? borderEnd : borderStart;
final int directionAwareBorderRight = isRTL ? borderStart : borderEnd;
borderLeft = directionAwareBorderLeft;
borderRight = directionAwareBorderRight;
} else {
final int directionAwareBorderLeft = isRTL ? borderEnd : borderStart;
final int directionAwareBorderRight = isRTL ? borderStart : borderEnd;
if (directionAwareBorderLeft >= 0) {
borderLeft = directionAwareBorderLeft;
}
if (directionAwareBorderRight >= 0) {
borderRight = directionAwareBorderRight;
}
}
}
int left = bounds.left;
int top = bounds.top;
@@ -961,7 +1007,12 @@ private void drawQuadrilateral(
}
private int getBorderWidth(int position) {
return mBorderWidth != null ? Math.round(mBorderWidth.get(position)) : 0;
if (mBorderWidth == null) {
return 0;
}
final float width = mBorderWidth.get(position);
return YogaConstants.isUndefined(width) ? -1 : Math.round(width);
}
private static int colorFromAlphaAndRGBComponents(float alpha, float rgb) {
@@ -21,7 +21,7 @@ public ReactViewBackgroundManager(View view) {
private ReactViewBackgroundDrawable getOrCreateReactViewBackground() {
if (mReactBackgroundDrawable == null) {
mReactBackgroundDrawable = new ReactViewBackgroundDrawable();
mReactBackgroundDrawable = new ReactViewBackgroundDrawable(mView.getContext());
Drawable backgroundDrawable = mView.getBackground();
ViewHelper.setBackground(
mView, null); // required so that drawable callback is cleared before we add the
@@ -24,6 +24,7 @@
import android.view.animation.Animation;
import com.facebook.infer.annotation.Assertions;
import com.facebook.react.common.annotations.VisibleForTesting;
import com.facebook.react.modules.i18nmanager.I18nUtil;
import com.facebook.react.touch.OnInterceptTouchEventListener;
import com.facebook.react.touch.ReactHitSlopView;
import com.facebook.react.touch.ReactInterceptingViewGroup;
@@ -105,10 +106,10 @@ public void onLayoutChange(
private boolean mNeedsOffscreenAlphaCompositing = false;
private final ViewGroupDrawingOrderHelper mDrawingOrderHelper;
private @Nullable Path mPath;
private int mLayoutDirection;
public ReactViewGroup(Context context) {
super(context);
mDrawingOrderHelper = new ViewGroupDrawingOrderHelper(this);
}
@@ -126,6 +127,15 @@ protected void onLayout(boolean changed, int left, int top, int right, int botto
// No-op since UIManagerModule handles actually laying out children.
}
@Override
public void onRtlPropertiesChanged(int layoutDirection) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (mReactBackgroundDrawable != null) {
mReactBackgroundDrawable.setLayoutDirection(mLayoutDirection);
}
}
}
@Override
public void requestLayout() {
// No-op, terminate `requestLayout` here, UIManagerModule handles laying out children and
@@ -565,7 +575,7 @@ public int getBackgroundColor() {
private ReactViewBackgroundDrawable getOrCreateReactViewBackground() {
if (mReactBackgroundDrawable == null) {
mReactBackgroundDrawable = new ReactViewBackgroundDrawable();
mReactBackgroundDrawable = new ReactViewBackgroundDrawable(getContext());
Drawable backgroundDrawable = getBackground();
updateBackgroundDrawable(
null); // required so that drawable callback is cleared before we add the
@@ -577,6 +587,14 @@ private ReactViewBackgroundDrawable getOrCreateReactViewBackground() {
new LayerDrawable(new Drawable[] {mReactBackgroundDrawable, backgroundDrawable});
updateBackgroundDrawable(layerDrawable);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
mLayoutDirection =
I18nUtil.getInstance().isRTL(getContext())
? LAYOUT_DIRECTION_RTL
: LAYOUT_DIRECTION_LTR;
mReactBackgroundDrawable.setLayoutDirection(mLayoutDirection);
}
}
return mReactBackgroundDrawable;
}
@@ -42,7 +42,13 @@
public static final String REACT_CLASS = ViewProps.VIEW_CLASS_NAME;
private static final int[] SPACING_TYPES = {
Spacing.ALL, Spacing.LEFT, Spacing.RIGHT, Spacing.TOP, Spacing.BOTTOM,
Spacing.ALL,
Spacing.LEFT,
Spacing.RIGHT,
Spacing.TOP,
Spacing.BOTTOM,
Spacing.START,
Spacing.END,
};
private static final int CMD_HOTSPOT_UPDATE = 1;
private static final int CMD_SET_PRESSED = 2;
@@ -127,13 +133,18 @@ public void setNeedsOffscreenAlphaCompositing(
view.setNeedsOffscreenAlphaCompositing(needsOffscreenAlphaCompositing);
}
@ReactPropGroup(names = {
@ReactPropGroup(
names = {
ViewProps.BORDER_WIDTH,
ViewProps.BORDER_LEFT_WIDTH,
ViewProps.BORDER_RIGHT_WIDTH,
ViewProps.BORDER_TOP_WIDTH,
ViewProps.BORDER_BOTTOM_WIDTH,
}, defaultFloat = YogaConstants.UNDEFINED)
ViewProps.BORDER_START_WIDTH,
ViewProps.BORDER_END_WIDTH,
},
defaultFloat = YogaConstants.UNDEFINED
)
public void setBorderWidth(ReactViewGroup view, int index, float width) {
if (!YogaConstants.isUndefined(width)) {
width = PixelUtil.toPixelFromDIP(width);

0 comments on commit 7ed7593

Please sign in to comment.