转载请注明出处:http://blog.youkuaiyun.com/binbinqq86/article/details/79463977
说起Android里面的自定义圆角圆形图片,已经算是老生常谈的话题了,之前一直使用别人的,最近使用的时候发现自己居然没有一个这样属于自己的工具库,实在遗憾,毕竟还是自己的东西用起来最顺手,所以就打造了一个,先来看看效果:
怎么样,还不错吧~支持各种图案,边框,各种圆角。其中原理也是很简单的,无非就是canvas知识的应用。接下来我们一个一个形状来看,首先是圆形,这个应该是最简单的了,直接使用canvas的drawCircle来绘制一个圆形就搞定了,看代码:
float r = hasBorder ? width / 2f - borderWidth : width / 2f;
canvas.drawCircle(width / 2f, height / 2f, r, mPaintDrawable);
其中的r就是圆的半径,这里我们用一个变量hasBorder 来区分是否绘制边框(边框后面细说),drawCircle的前两个参数就是圆心坐标,最后一个参数则是画笔,我们的图片呢???确定这样就能画出来圆形图片???其实图片被我们封装在笔刷里面了:BitmapShader。这个类的使用很简单,官方文档是这样解释的:
Shader used to draw a bitmap as a texture.
就是使用特定的图片来作为纹理使用。这里就不再详细解释这个类的使用了,不懂的同学可以参考文章最后的链接。其实除了使用BitmapShader还有另外一种方案,就是PorterDuffXfermode,感兴趣的可以参考我之前的一篇文章:http://blog.youkuaiyun.com/binbinqq86/article/details/78329238,里面讲述了另外一种实现圆形图片的方案。
下面来看一下获取Bitmap的方法:
/**
* 获取imageview设置的图片(针对大图,此时必须已经处理过了,否则会造成内存溢出)
* <p>
* 获取bitmap:
* 1、如果设置了src为图片则返回该图片,
* 2、如果设置了src为颜色值则返回颜色值,
* 3、如果没有设置src,则返回默认颜色值(未设置则为透明)
*
* @param drawable
* @return
*/
private Bitmap getBitmap(Drawable drawable) {
Bitmap bitmap = null;
if (drawable instanceof BitmapDrawable) {
bitmap = ((BitmapDrawable) drawable).getBitmap();
} else if (drawable instanceof ColorDrawable) {
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bitmap);
int color = ((ColorDrawable) drawable).getColor();
c.drawARGB(Color.alpha(color), Color.red(color), Color.green(color), Color.blue(color));
} else {
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bitmap);
c.drawARGB(Color.alpha(defaultColor), Color.red(defaultColor), Color.green(defaultColor), Color.blue(defaultColor));
}
if (isBlur) {
//高斯模糊
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
try {
bitmap = RSBlur.blur(getContext(), bitmap, (int) blurRadius);
} catch (Exception e) {
bitmap = FastBlur.blur(bitmap, (int) blurRadius, true);
}
} else {
bitmap = FastBlur.blur(bitmap, (int) blurRadius, true);
}
}
return bitmap;
}
这里就是获取imageview设置的图片,然后就可以随意绘制我们想要的效果了,这里我们取图片的中间区域进行绘制,可以防止图片跟视图大小不一样(前提是我们已经根据imageView的宽高去缩放过图片了,这里处理的只是绘制部分,类似imageView的centerCrop),看代码:
/**
* 处理图片大于或者小于控件的情况
* (不是针对大图内存溢出的处理,此处的处理只是为了让图片居中绘制——centerCrop:参照imageView的处理)
*
* @param bitmap
*/
private void setUpShader(Bitmap bitmap) {
mBitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
int dWidth = bitmap.getWidth();
int dHeight = bitmap.getHeight();
int vWidth = width;
int vHeight = height;
if (hasBorder) {
vWidth -= 2 * borderWidth;
vHeight -= 2 * borderWidth;
}
if (dWidth == vWidth && dHeight == vHeight) {
} else {
float scale = 1.0f;
float dx = 0, dy = 0;
if (dWidth * vHeight > vWidth * dHeight) {
scale = (float) vHeight / (float) dHeight;
dx = (vWidth - dWidth * scale) * 0.5f;
} else {
scale = (float) vWidth / (float) dWidth;
dy = (vHeight - dHeight * scale) * 0.5f;
}
mMatrix