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

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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
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());
...
}

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
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);
}
}
}

效果如下:

    

作者:AngelDevil
出处:http://www.angeldevil.me
原文链接:http://www.angeldevil.me/2014/12/29/rounded-image/

转载请注明出处!