Android Round Corner ImageView
Making round corners on the image by using a mask Put an ImageView and a mask view in a RelativeLayout. Make the mask view round corners and put it on top of the ImageView.
The layout:
The drawable round_corners_mask.xml
Apply round corner image transformation when loading the image through Picasso.
The round corner transformation class. RoundCornersTransformation.java
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
import android.graphics.Shader;
// enables hardware accelerated rounded corners
// original idea here : http://www.curious-creature.org/2012/12/11/android-recipe-1-image-with-rounded-corners/
// https://gist.github.com/aprock/6213395
// https://gist.github.com/amardeshbd/06b491d4adb568b1b226a20d4953a180
public class RoundCornersTransformation implements com.squareup.picasso.Transformation {
private final int radius; // dp
private final int margin; // dp
private String KEY = "";
private boolean topCorners = true;
private boolean bottomCorners = true;
/**
* Creates rounded transformation for all corners.
*
* @param radius radius is corner radii in dp
* @param margin margin is the board in dp
*/
public RoundCornersTransformation(final int radius, final int margin) {
this.radius = radius;
this.margin = margin;
if (KEY.isEmpty()) KEY = "rounded_" + radius + margin;
}
/**
* Creates rounded transformation for top or bottom corners.
*
* @param radius radius is corner radii in dp
* @param margin margin is the board in dp
* @param topCornersOnly Rounded corner for top corners only.
* @param bottomCornersOnly Rounded corner for bottom corners only.
*/
public RoundCornersTransformation(final int radius, final int margin, boolean topCornersOnly,
boolean bottomCornersOnly) {
this(radius, margin);
topCorners = topCornersOnly;
bottomCorners = bottomCornersOnly;
KEY = "rounded_" + radius + margin + topCorners + bottomCorners;
}
@Override
public Bitmap transform(final Bitmap source) {
final Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setShader(new BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP));
Bitmap output = Bitmap.createBitmap(source.getWidth(), source.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
if(topCorners && bottomCorners) {
// Uses native method to draw symmetric rounded corners
canvas.drawRoundRect(new RectF(margin, margin, source.getWidth() - margin,
source.getHeight() - margin), radius, radius, paint);
} else {
// Uses custom path to generate rounded corner individually
canvas.drawPath(RoundedRect(margin, margin, source.getWidth() - margin,
source.getHeight() - margin, radius, radius, topCorners, topCorners,
bottomCorners, bottomCorners), paint);
}
if (source != output) {
source.recycle();
}
return output;
}
@Override
public String key() {
return "rounded_" + radius + margin;
// return KEY;
}
/**
* Prepares a path for rounded corner selectively.
* Source taken from http://stackoverflow.com/a/35668889/6635889
* @param leftX The X coordinate of the left side of the rectangle
* @param topY The Y coordinate of the top of the rectangle
* @param rightX The X coordinate of the right side of the rectangle
* @param bottomY The Y coordinate of the bottom of the rectangle
* @param rx The x-radius of the oval used to round the corners
* @param ry The y-radius of the oval used to round the corners
* @param topLeft
* @param topRight
* @param bottomRight
* @param bottomLeft
* @return
*/
public static Path RoundedRect(float leftX, float topY, float rightX, float bottomY, float rx,
float ry, boolean topLeft, boolean topRight, boolean
bottomRight, boolean bottomLeft) {
Path path = new Path();
if (rx < 0) rx = 0;
if (ry < 0) ry = 0;
float width = rightX - leftX;
float height = bottomY - topY;
if (rx > width / 2) rx = width / 2;
if (ry > height / 2) ry = height / 2;
float widthMinusCorners = (width - (2 * rx));
float heightMinusCorners = (height - (2 * ry));
path.moveTo(rightX, topY + ry);
if (topRight)
path.rQuadTo(0, -ry, -rx, -ry);//top-right corner
else{
path.rLineTo(0, -ry);
path.rLineTo(-rx,0);
}
path.rLineTo(-widthMinusCorners, 0);
if (topLeft)
path.rQuadTo(-rx, 0, -rx, ry); //top-left corner
else{
path.rLineTo(-rx, 0);
path.rLineTo(0,ry);
}
path.rLineTo(0, heightMinusCorners);
if (bottomLeft)
path.rQuadTo(0, ry, rx, ry);//bottom-left corner
else{
path.rLineTo(0, ry);
path.rLineTo(rx,0);
}
path.rLineTo(widthMinusCorners, 0);
if (bottomRight)
path.rQuadTo(rx, 0, rx, -ry); //bottom-right corner
else{
path.rLineTo(rx,0);
path.rLineTo(0, -ry);
}
path.rLineTo(0, -heightMinusCorners);
path.close();//Given close, last lineto can be removed.
return path;
}
}
Using the transformation with Picasso.
Picasso.with(this)
.load("http://www.gettyimages.ca/gi-resources/images/Homepage/Hero/UK/CMS_Creative_164657191_Kingfisher.jpg")
.transform(new RoundCornersTransformation(20, 20, true, true))
.into(anImageView);
Making round corners by overriding the onDraw method of the ImageView. RoundCornersImageView.java
import android.annotation.TargetApi;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Path;
import android.graphics.RectF;
import android.os.Build;
import android.util.AttributeSet;
import android.widget.ImageView;
public class RoundCornersImageView extends ImageView {
public RoundCornersImageView(Context context) {
super(context);
}
public RoundCornersImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public RoundCornersImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public RoundCornersImageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
}
@Override
protected boolean setFrame(int l, int t, int r, int b) {
return super.setFrame(l, t, r, b);
}
@Override
protected void onDraw(Canvas canvas) {
float radius = getContext().getResources().getDimension(R.dimen.round_corner_radius);
Path path = new Path();
RectF rect = new RectF(0, 0, this.getWidth(), this.getHeight());
path.addRoundRect(rect, radius, radius, Path.Direction.CW);
canvas.clipPath(path);
super.onDraw(canvas);
}
}
Use it like this:
Making a custom ImageView with options to choose the corners to be rounded.
attrs.xml
RoundishImageView.java
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Path;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ImageView;
public class RoundishImageView extends ImageView {
public static final int CORNER_NONE = 0;
public static final int CORNER_TOP_LEFT = 1;
public static final int CORNER_TOP_RIGHT = 2;
public static final int CORNER_BOTTOM_RIGHT = 4;
public static final int CORNER_BOTTOM_LEFT = 8;
public static final int CORNER_ALL = 15;
private final RectF cornerRect = new RectF();
private final Path path = new Path();
private int cornerRadius;
private int roundedCorners;
public RoundishImageView(Context context) {
this(context, null);
}
public RoundishImageView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public RoundishImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.RoundishImageView);
cornerRadius = a.getDimensionPixelSize(R.styleable.RoundishImageView_cornerRadius, 0);
roundedCorners = a.getInt(R.styleable.RoundishImageView_roundedCorners, CORNER_NONE);
a.recycle();
}
public void setCornerRadius(int radius) {
cornerRadius = radius;
setPath();
invalidate();
}
public int getRadius() {
return cornerRadius;
}
public void setRoundedCorners(int corners) {
roundedCorners = corners;
setPath();
invalidate();
}
public int getRoundedCorners() {
return roundedCorners;
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
setPath();
}
@Override
protected void onDraw(Canvas canvas) {
if (!path.isEmpty()) {
canvas.clipPath(path);
}
super.onDraw(canvas);
}
private void setPath() {
path.rewind();
if (cornerRadius >= 1f && roundedCorners != CORNER_NONE) {
final int width = getWidth();
final int height = getHeight();
final float twoRadius = cornerRadius * 2;
cornerRect.set(-cornerRadius, -cornerRadius, cornerRadius, cornerRadius);
if (isRounded(CORNER_TOP_LEFT)) {
cornerRect.offsetTo(0f, 0f);
path.arcTo(cornerRect, 180f, 90f);
} else {
path.moveTo(0f, 0f);
}
if (isRounded(CORNER_TOP_RIGHT)) {
cornerRect.offsetTo(width - twoRadius, 0f);
path.arcTo(cornerRect, 270f, 90f);
} else {
path.lineTo(width, 0f);
}
if (isRounded(CORNER_BOTTOM_RIGHT)) {
cornerRect.offsetTo(width - twoRadius, height - twoRadius);
path.arcTo(cornerRect, 0f, 90f);
} else {
path.lineTo(width, height);
}
if (isRounded(CORNER_BOTTOM_LEFT)) {
cornerRect.offsetTo(0f, height - twoRadius);
path.arcTo(cornerRect, 90f, 90f);
} else {
path.lineTo(0f, height);
}
path.close();
}
}
private boolean isRounded(int corner) {
return (roundedCorners & corner) == corner;
}
}
Use it like this:
Search within Codexpedia
Custom Search
Search the entire web
Custom Search
Related Posts