Skip to content

Commit

Permalink
Added support for corner radii in Android
Browse files Browse the repository at this point in the history
Summary:
This is a cut down version of a previous pull request with just the 4 corners catered for.
Closes #4252

Reviewed By: svcscm

Differential Revision: D2911959

Pulled By: androidtrunkagent

fb-gh-sync-id: 7ddcd684d90d4d92ccefed906c0126e92818dcde
  • Loading branch information
mattds authored and facebook-github-bot-7 committed Feb 8, 2016
1 parent 17fcc94 commit 4937a4c
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 12 deletions.
29 changes: 29 additions & 0 deletions Examples/UIExplorer/BorderExample.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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]} />;
}
},
];
Original file line number Diff line number Diff line change
Expand Up @@ -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
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

import javax.annotation.Nullable;

import java.util.Arrays;
import java.util.Locale;

import android.graphics.Canvas;
Expand Down Expand Up @@ -78,7 +79,9 @@ private static enum BorderStyle {
/* 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;

Expand All @@ -87,9 +90,11 @@ private static enum BorderStyle {
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);
Expand Down Expand Up @@ -132,11 +137,10 @@ public void getOutline(Outline outline) {
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());
}
Expand Down Expand Up @@ -181,8 +185,22 @@ public void setBorderStyle(@Nullable String style) {
}

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();
}
}
Expand Down Expand Up @@ -225,19 +243,61 @@ private void updatePath() {
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,10 @@ public void setBorderRadius(float borderRadius) {
getOrCreateReactViewBackground().setRadius(borderRadius);
}

public void setBorderRadius(float borderRadius, int position) {
getOrCreateReactViewBackground().setRadius(borderRadius, position);
}

public void setBorderStyle(@Nullable String style) {
getOrCreateReactViewBackground().setBorderStyle(style);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,23 @@ public void setAccessible(ReactViewGroup view, boolean accessible) {
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")
Expand Down

0 comments on commit 4937a4c

Please sign in to comment.