Android: Implement border(Start|End)Width for non-rounded borders
Reviewed By: achen1 Differential Revision: D5917755 fbshipit-source-id: 3ec0ab1a1e191f5f6fd956691995e95937a513cc
This commit is contained in:
parent
04a8c62313
commit
7ed7593b2b
|
@ -624,18 +624,24 @@ public class LayoutShadowNode extends ReactShadowNodeImpl {
|
|||
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 class ViewProps {
|
|||
|
||||
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 class ViewProps {
|
|||
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.RectF;
|
|||
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 @@ public class ReactViewBackgroundDrawable extends Drawable {
|
|||
private int mAlpha = 255;
|
||||
|
||||
private @Nullable float[] mBorderCornerRadii;
|
||||
private final Context mContext;
|
||||
|
||||
public enum BorderRadiusLocation {
|
||||
TOP_LEFT,
|
||||
|
@ -113,6 +117,10 @@ public class ReactViewBackgroundDrawable extends Drawable {
|
|||
BOTTOM_LEFT
|
||||
}
|
||||
|
||||
public ReactViewBackgroundDrawable(Context context) {
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
updatePathEffect();
|
||||
|
@ -810,9 +818,14 @@ public class ReactViewBackgroundDrawable extends Drawable {
|
|||
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 @@ public class ReactViewBackgroundDrawable extends Drawable {
|
|||
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 @@ public class ReactViewBackgroundDrawable extends Drawable {
|
|||
}
|
||||
|
||||
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 class ReactViewBackgroundManager {
|
|||
|
||||
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.ViewGroup;
|
|||
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 class ReactViewGroup extends ViewGroup implements
|
|||
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 @@ public class ReactViewGroup extends ViewGroup implements
|
|||
// 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 class ReactViewGroup extends ViewGroup implements
|
|||
|
||||
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 @@ public class ReactViewGroup extends ViewGroup implements
|
|||
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 class ReactViewManager extends ViewGroupManager<ReactViewGroup> {
|
|||
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 class ReactViewManager extends ViewGroupManager<ReactViewGroup> {
|
|||
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);
|
||||
|
|
Loading…
Reference in New Issue