关于圆角图片的实现,网上应该有很多例子,主要就是使用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/
转载请注明出处!