Added support for corner radii in Android
Summary: This is a cut down version of a previous pull request with just the 4 corners catered for. Closes https://github.com/facebook/react-native/pull/4252 Reviewed By: svcscm Differential Revision: D2911959 Pulled By: androidtrunkagent fb-gh-sync-id: 7ddcd684d90d4d92ccefed906c0126e92818dcde
This commit is contained in:
parent
17fcc9440f
commit
4937a4c5cd
|
@ -98,6 +98,20 @@ var styles = StyleSheet.create({
|
|||
marginRight: 10,
|
||||
backgroundColor: 'lightgrey',
|
||||
},
|
||||
border9: {
|
||||
borderWidth: 10,
|
||||
borderTopLeftRadius: 10,
|
||||
borderBottomRightRadius: 20,
|
||||
borderColor: 'black',
|
||||
},
|
||||
border10: {
|
||||
borderWidth: 10,
|
||||
backgroundColor: 'white',
|
||||
borderTopLeftRadius: 10,
|
||||
borderBottomRightRadius: 20,
|
||||
borderColor: 'black',
|
||||
elevation: 10
|
||||
}
|
||||
});
|
||||
|
||||
exports.title = 'Border';
|
||||
|
@ -180,4 +194,19 @@ exports.examples = [
|
|||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Corner Radii',
|
||||
description: 'borderTopLeftRadius & borderBottomRightRadius',
|
||||
render() {
|
||||
return <View style={[styles.box, styles.border9]} />;
|
||||
}
|
||||
},
|
||||
{
|
||||
title: 'Corner Radii / Elevation',
|
||||
description: 'borderTopLeftRadius & borderBottomRightRadius & elevation',
|
||||
platform: 'android',
|
||||
render() {
|
||||
return <View style={[styles.box, styles.border10]} />;
|
||||
}
|
||||
},
|
||||
];
|
||||
|
|
|
@ -77,6 +77,11 @@ public class ViewProps {
|
|||
public static final String BORDER_TOP_WIDTH = "borderTopWidth";
|
||||
public static final String BORDER_RIGHT_WIDTH = "borderRightWidth";
|
||||
public static final String BORDER_BOTTOM_WIDTH = "borderBottomWidth";
|
||||
public static final String BORDER_RADIUS = "borderRadius";
|
||||
public static final String BORDER_TOP_LEFT_RADIUS = "borderTopLeftRadius";
|
||||
public static final String BORDER_TOP_RIGHT_RADIUS = "borderTopRightRadius";
|
||||
public static final String BORDER_BOTTOM_LEFT_RADIUS = "borderBottomLeftRadius";
|
||||
public static final String BORDER_BOTTOM_RIGHT_RADIUS = "borderBottomRightRadius";
|
||||
public static final int[] BORDER_SPACING_TYPES = {
|
||||
Spacing.ALL, Spacing.LEFT, Spacing.RIGHT, Spacing.TOP, Spacing.BOTTOM
|
||||
};
|
||||
|
|
|
@ -11,6 +11,7 @@ package com.facebook.react.views.view;
|
|||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
|
||||
import android.graphics.Canvas;
|
||||
|
@ -78,7 +79,9 @@ import com.facebook.csslayout.Spacing;
|
|||
/* Used for rounded border and rounded background */
|
||||
private @Nullable PathEffect mPathEffectForBorderStyle;
|
||||
private @Nullable Path mPathForBorderRadius;
|
||||
private @Nullable Path mPathForBorderRadiusOutline;
|
||||
private @Nullable RectF mTempRectForBorderRadius;
|
||||
private @Nullable RectF mTempRectForBorderRadiusOutline;
|
||||
private boolean mNeedUpdatePathForBorderRadius = false;
|
||||
private float mBorderRadius = CSSConstants.UNDEFINED;
|
||||
|
||||
|
@ -87,9 +90,11 @@ import com.facebook.csslayout.Spacing;
|
|||
private int mColor = Color.TRANSPARENT;
|
||||
private int mAlpha = 255;
|
||||
|
||||
private @Nullable float[] mBorderCornerRadii;
|
||||
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
if (!CSSConstants.isUndefined(mBorderRadius) && mBorderRadius > 0) {
|
||||
if ((!CSSConstants.isUndefined(mBorderRadius) && mBorderRadius > 0) || mBorderCornerRadii != null) {
|
||||
drawRoundedBackgroundWithBorders(canvas);
|
||||
} else {
|
||||
drawRectangularBackgroundWithBorders(canvas);
|
||||
|
@ -132,11 +137,10 @@ import com.facebook.csslayout.Spacing;
|
|||
super.getOutline(outline);
|
||||
return;
|
||||
}
|
||||
if(!CSSConstants.isUndefined(mBorderRadius) && mBorderRadius > 0) {
|
||||
float extraRadiusFromBorderWidth = (mBorderWidth != null)
|
||||
? mBorderWidth.get(Spacing.ALL) / 2f
|
||||
: 0;
|
||||
outline.setRoundRect(getBounds(), mBorderRadius + extraRadiusFromBorderWidth);
|
||||
if((!CSSConstants.isUndefined(mBorderRadius) && mBorderRadius > 0) || mBorderCornerRadii != null) {
|
||||
updatePath();
|
||||
|
||||
outline.setConvexPath(mPathForBorderRadiusOutline);
|
||||
} else {
|
||||
outline.setRect(getBounds());
|
||||
}
|
||||
|
@ -181,8 +185,22 @@ import com.facebook.csslayout.Spacing;
|
|||
}
|
||||
|
||||
public void setRadius(float radius) {
|
||||
if (mBorderRadius != radius) {
|
||||
if (!FloatUtil.floatsEqual(mBorderRadius,radius)) {
|
||||
mBorderRadius = radius;
|
||||
mNeedUpdatePathForBorderRadius = true;
|
||||
invalidateSelf();
|
||||
}
|
||||
}
|
||||
|
||||
public void setRadius(float radius, int position) {
|
||||
if (mBorderCornerRadii == null) {
|
||||
mBorderCornerRadii = new float[4];
|
||||
Arrays.fill(mBorderCornerRadii, CSSConstants.UNDEFINED);
|
||||
}
|
||||
|
||||
if (!FloatUtil.floatsEqual(mBorderCornerRadii[position], radius)) {
|
||||
mBorderCornerRadii[position] = radius;
|
||||
mNeedUpdatePathForBorderRadius = true;
|
||||
invalidateSelf();
|
||||
}
|
||||
}
|
||||
|
@ -225,19 +243,61 @@ import com.facebook.csslayout.Spacing;
|
|||
if (mPathForBorderRadius == null) {
|
||||
mPathForBorderRadius = new Path();
|
||||
mTempRectForBorderRadius = new RectF();
|
||||
mPathForBorderRadiusOutline = new Path();
|
||||
mTempRectForBorderRadiusOutline = new RectF();
|
||||
}
|
||||
|
||||
mPathForBorderRadius.reset();
|
||||
mPathForBorderRadiusOutline.reset();
|
||||
|
||||
mTempRectForBorderRadius.set(getBounds());
|
||||
mTempRectForBorderRadiusOutline.set(getBounds());
|
||||
float fullBorderWidth = getFullBorderWidth();
|
||||
if (fullBorderWidth > 0) {
|
||||
mTempRectForBorderRadius.inset(fullBorderWidth * 0.5f, fullBorderWidth * 0.5f);
|
||||
}
|
||||
|
||||
float defaultBorderRadius = !CSSConstants.isUndefined(mBorderRadius) ? mBorderRadius : 0;
|
||||
float topLeftRadius = mBorderCornerRadii != null && !CSSConstants.isUndefined(mBorderCornerRadii[0]) ? mBorderCornerRadii[0] : defaultBorderRadius;
|
||||
float topRightRadius = mBorderCornerRadii != null && !CSSConstants.isUndefined(mBorderCornerRadii[1]) ? mBorderCornerRadii[1] : defaultBorderRadius;
|
||||
float bottomRightRadius = mBorderCornerRadii != null && !CSSConstants.isUndefined(mBorderCornerRadii[2]) ? mBorderCornerRadii[2] : defaultBorderRadius;
|
||||
float bottomLeftRadius = mBorderCornerRadii != null && !CSSConstants.isUndefined(mBorderCornerRadii[3]) ? mBorderCornerRadii[3] : defaultBorderRadius;
|
||||
|
||||
|
||||
mPathForBorderRadius.addRoundRect(
|
||||
mTempRectForBorderRadius,
|
||||
mBorderRadius,
|
||||
mBorderRadius,
|
||||
new float[] {
|
||||
topLeftRadius,
|
||||
topLeftRadius,
|
||||
topRightRadius,
|
||||
topRightRadius,
|
||||
bottomRightRadius,
|
||||
bottomRightRadius,
|
||||
bottomLeftRadius,
|
||||
bottomLeftRadius
|
||||
},
|
||||
Path.Direction.CW);
|
||||
|
||||
float extraRadiusForOutline = 0;
|
||||
|
||||
if (mBorderWidth != null) {
|
||||
extraRadiusForOutline = mBorderWidth.get(Spacing.ALL) / 2f;
|
||||
}
|
||||
|
||||
mPathForBorderRadiusOutline.addRoundRect(
|
||||
mTempRectForBorderRadiusOutline,
|
||||
new float[] {
|
||||
topLeftRadius + extraRadiusForOutline,
|
||||
topLeftRadius + extraRadiusForOutline,
|
||||
topRightRadius + extraRadiusForOutline,
|
||||
topRightRadius + extraRadiusForOutline,
|
||||
bottomRightRadius + extraRadiusForOutline,
|
||||
bottomRightRadius + extraRadiusForOutline,
|
||||
bottomLeftRadius + extraRadiusForOutline,
|
||||
bottomLeftRadius + extraRadiusForOutline
|
||||
},
|
||||
Path.Direction.CW);
|
||||
|
||||
mPathEffectForBorderStyle = mBorderStyle != null
|
||||
? mBorderStyle.getPathEffect(getFullBorderWidth())
|
||||
: null;
|
||||
|
|
|
@ -207,6 +207,10 @@ public class ReactViewGroup extends ViewGroup implements
|
|||
getOrCreateReactViewBackground().setRadius(borderRadius);
|
||||
}
|
||||
|
||||
public void setBorderRadius(float borderRadius, int position) {
|
||||
getOrCreateReactViewBackground().setRadius(borderRadius, position);
|
||||
}
|
||||
|
||||
public void setBorderStyle(@Nullable String style) {
|
||||
getOrCreateReactViewBackground().setBorderStyle(style);
|
||||
}
|
||||
|
|
|
@ -51,9 +51,23 @@ public class ReactViewManager extends ViewGroupManager<ReactViewGroup> {
|
|||
view.setFocusable(accessible);
|
||||
}
|
||||
|
||||
@ReactProp(name = "borderRadius")
|
||||
public void setBorderRadius(ReactViewGroup view, float borderRadius) {
|
||||
view.setBorderRadius(PixelUtil.toPixelFromDIP(borderRadius));
|
||||
@ReactPropGroup(names = {
|
||||
ViewProps.BORDER_RADIUS,
|
||||
ViewProps.BORDER_TOP_LEFT_RADIUS,
|
||||
ViewProps.BORDER_TOP_RIGHT_RADIUS,
|
||||
ViewProps.BORDER_BOTTOM_RIGHT_RADIUS,
|
||||
ViewProps.BORDER_BOTTOM_LEFT_RADIUS
|
||||
}, defaultFloat = CSSConstants.UNDEFINED)
|
||||
public void setBorderRadius(ReactViewGroup view, int index, float borderRadius) {
|
||||
if (!CSSConstants.isUndefined(borderRadius)) {
|
||||
borderRadius = PixelUtil.toPixelFromDIP(borderRadius);
|
||||
}
|
||||
|
||||
if (index == 0) {
|
||||
view.setBorderRadius(borderRadius);
|
||||
} else {
|
||||
view.setBorderRadius(borderRadius, index - 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ReactProp(name = "borderStyle")
|
||||
|
|
Loading…
Reference in New Issue