您的位置:首页 > 其它

圆角图片,可以指定特定的角为圆角

2015-12-17 17:08 316 查看
原网地址:http://www.angeldevil.me/2014/12/29/rounded-image/

关于圆角图片的实现,网上应该有很多例子,主要就是使用BitmapShader,比如Universal-Image-Loader中的RoundedBitmapDisplayer,本文中的实现都是基于这个RoundedBitmapDisplayer。

RoundedBItmapDisplayer通过我们指定的Bitmap生成了一个BitmapShader并与Paint关联,在draw里面使用这个Paint进行drawRoundRect,drawRoundRect是Canvas的API,用于画一个圆角距形,但如果我们不想让4个角都是圆角呢,比如只想要左边的两个角是圆角?

开始我是这么想的,调用drawRoundRect时指定的Rect的宽度超出View宽度cornerRadius大小,这样右边两个圆角超出了View的区域就不会被显示出来,就只有左边两个角是圆角了,像下面这样(所有的修改基于RoundedBitmapDisplayer):

public RoundedDrawable(Bitmap bitmap, int cornerRadius) {
...
mBitmapRect = new RectF(0, 0, bitmap.getWidth() + cornerRadius, bitmap.getHeight());
...
}

@Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
mRect.set(0, 0, bounds.width() + cornerRadius, bounds.height());
...
}


但这样图片应该会变形或被截断什么的,并且如果我只想要左上角和右下角是圆角呢?

然后就想到了接下来的方法,先像原来一样画一个圆角距形的图片,再把不需要圆角的角画出来,这样就只有指定的角是圆角了,完整代码如下:

public class RoundedImageView extends ImageView {

public static final int CORNER_NONE = 0;
public static final int CORNER_TOP_LEFT = 1;
public static final int CORNER_TOP_RIGHT = 1 << 1;
public static final int CORNER_BOTTOM_LEFT = 1 << 2;
public static final int CORNER_BOTTOM_RIGHT = 1 << 3;
public static final int CORNER_ALL = CORNER_TOP_LEFT | CORNER_TOP_RIGHT | CORNER_BOTTOM_LEFT | CORNER_BOTTOM_RIGHT;

public RoundedImageView(Context context) {
super(context);
}

public RoundedImageView(Context context, AttributeSet attrs) {
super(context, attrs);
}

public void setImage(Bitmap bmp, int radius, int corners) {
setImageDrawable(new RoundedDrawable(bmp, radius, corners));
}

public static class RoundedDrawable extends Drawable {

protected final float cornerRadius;

protected final RectF mRect = new RectF(), mBitmapRect;
protected final BitmapShader bitmapShader;
protected final Paint paint;
private int corners;

public RoundedDrawable(Bitmap bitmap, int cornerRadius, int corners) {
this.cornerRadius = cornerRadius;
this.corners = corners;

bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
mBitmapRect = new RectF(0, 0, bitmap.getWidth(), bitmap.getHeight());

paint = new Paint();
paint.setAntiAlias(true);
paint.setShader(bitmapShader);
}

@Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
mRect.set(0, 0, bounds.width(), bounds.height());

// Resize the original bitmap to fit the new bound
Matrix shaderMatrix = new Matrix();
shaderMatrix.setRectToRect(mBitmapRect, mRect, Matrix.ScaleToFit.FILL);
bitmapShader.setLocalMatrix(shaderMatrix);

}

@Override
public void draw(Canvas canvas) {
canvas.drawRoundRect(mRect, cornerRadius, cornerRadius, paint);
int notRoundedCorners = corners ^ CORNER_ALL;
if ((notRoundedCorners & CORNER_TOP_LEFT) != 0) {
canvas.drawRect(0, 0, cornerRadius, cornerRadius, paint);
}
if ((notRoundedCorners & CORNER_TOP_RIGHT) != 0) {
canvas.drawRect(mRect.right - cornerRadius, 0, mRect.right, cornerRadius, paint);
}
if ((notRoundedCorners & CORNER_BOTTOM_LEFT) != 0) {
canvas.drawRect(0, mRect.bottom - cornerRadius, cornerRadius, mRect.bottom, paint);
}
if ((notRoundedCorners & CORNER_BOTTOM_RIGHT) != 0) {
canvas.drawRect(mRect.right - cornerRadius, mRect.bottom - cornerRadius, mRect.right, mRect.bottom, paint);
}
}

@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}

@Override
public void setAlpha(int alpha) {
paint.setAlpha(alpha);
}

@Override
public void setColorFilter(ColorFilter cf) {
paint.setColorFilter(cf);
}
}
}


效果如下:



注:实现该功能的大概原理是

1、先画一个圆角的矩形

canvas.drawRoundRect(mRect, cornerRadius, cornerRadius, paint);

2、对不需要显示圆角的地方重画,如(遮罩住左上角的圆角)

canvas.drawRect(0, 0, cornerRadius, cornerRadius, paint);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: