Android自定义圆角矩形ImageView,支持Glide加载图片及颜色填充
Posted 宿罪
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android自定义圆角矩形ImageView,支持Glide加载图片及颜色填充相关的知识,希望对你有一定的参考价值。
前言:
之前用到圆角的情况大都是自定义一个shape背景drawable及用到v7包下的CardView包裹View实现圆角矩形效果,还有就是在用户圆形头像的时候需要使用到圆角矩形(圆形可以看做是特殊的圆角矩形),诸如Button,Editext,TextView的圆角矩形颜色背景可以用shape实现,但是ImageView Res圆角还没用到过,它就不能简单地设置一个圆角矩形shape作为背景了。这篇文章将介绍如何自定义一个ImageView实现image圆角矩形的效果及加上Glide和颜色填充的支持。效果如下:
- 第一张图片为用Glide加载的远程图片;
- 第二张为本地图片(drawable);
- 第三张则为颜色填充。
代码编写
1. 继承AppCompatImageView,初始化
google推荐继承AppCompatImageView实现自定义ImageView实现更好地兼容。
/**
* 默认的圆角大小,单位为dp
*/
private static final float DEFAULT_CORNER = 10;
private Paint mPaint;
private int mCorner;
public RoundRectImageView(Context context)
this(context,null);
public RoundRectImageView(Context context, AttributeSet attrs)
this(context, attrs,0);
public RoundRectImageView(Context context, AttributeSet attrs, int defStyle)
super(context, attrs, defStyle);
mPaint = new Paint();
TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.RoundRectImageView);
mCorner = (int) typedArray.getDimension(R.styleable.RoundRectImageView_corner, dp2px(context, DEFAULT_CORNER));
typedArray.recycle();
这里自定义了一个属性corner:
<declare-styleable name="RoundRectImageView">
<attr name="corner" format="dimension"></attr>
</declare-styleable>
2. 重写onDraw(),裁剪图片
/**
* 绘制圆角矩形图片
*/
@Override
protected void onDraw(Canvas canvas)
Drawable drawable = getDrawable();
if ( drawable != null )
Bitmap bitmap = null;
// Drawable转Bitmap
if(drawable instanceof GlideBitmapDrawable)
bitmap = ((GlideBitmapDrawable)drawable).getBitmap();
else if(drawable instanceof ColorDrawable)
bitmap = Bitmap.createBitmap(getWidth(),getHeight(),
Config.ARGB_8888);
bitmap.eraseColor(((ColorDrawable) drawable).getColor());//填充颜色
else
bitmap = ((BitmapDrawable)drawable).getBitmap();
Bitmap roundBitmap = getRoundBitmap(bitmap, mCorner);
final Rect rectSrc = new Rect(0, 0, roundBitmap.getWidth(), roundBitmap.getHeight());
final Rect rectDest = new Rect(0,0,getWidth(),getHeight());
// 重置画笔,不然会留下黑色区域
mPaint.reset();
canvas.drawBitmap(roundBitmap, rectSrc, rectDest, mPaint);
else
super.onDraw(canvas);
其中的原理是先通过Drawable拿到Bitmap,对Bitmap进行裁剪,然后重绘Bitmap实现圆角矩形的效果。其中裁剪方法为:
/**
* 裁剪图片
* @param bitmap
* @param corner
* @return Bitmap
*/
private Bitmap getRoundBitmap(Bitmap bitmap, int corner)
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final Rect rect = new Rect(getPaddingLeft(), getPaddingTop(), bitmap.getWidth()-getPaddingRight(), bitmap.getHeight()-getPaddingBottom());
final RectF rectF = new RectF(rect);
mPaint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
mPaint.setColor(Color.WHITE);
canvas.drawRoundRect(rectF, corner, corner, mPaint);
// 设置图像混合模式为SRC_IN,裁剪出我们的圆角Bitmap
mPaint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, mPaint);
return output;
其中裁剪原理是通过两个图像进行混合,这里为SRC_IN模式,即可裁剪出我们需要的圆角矩形图像。
完整代码如下:
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.support.v7.widget.AppCompatImageView;
import android.util.AttributeSet;
import com.bumptech.glide.load.resource.bitmap.GlideBitmapDrawable;
/**
* 自定义圆角矩形ImageView
* Created by LT on 2018/5/13.
*/
public class RoundRectImageView extends AppCompatImageView
/**
* 默认的圆角大小,单位为dp
*/
private static final float DEFAULT_CORNER = 10;
private Paint mPaint;
private int mCorner;
public RoundRectImageView(Context context)
this(context,null);
public RoundRectImageView(Context context, AttributeSet attrs)
this(context, attrs,0);
public RoundRectImageView(Context context, AttributeSet attrs, int defStyle)
super(context, attrs, defStyle);
mPaint = new Paint();
TypedArray typedArray = context.obtainStyledAttributes(attrs,R.styleable.RoundRectImageView);
mCorner = (int) typedArray.getDimension(R.styleable.RoundRectImageView_corner, dp2px(context, DEFAULT_CORNER));
typedArray.recycle();
/**
* 绘制圆角矩形图片
*/
@Override
protected void onDraw(Canvas canvas)
Drawable drawable = getDrawable();
if ( drawable != null )
Bitmap bitmap = null;
// Drawable转Bitmap
if(drawable instanceof GlideBitmapDrawable)
bitmap = ((GlideBitmapDrawable)drawable).getBitmap();
else if(drawable instanceof ColorDrawable)
bitmap = Bitmap.createBitmap(getWidth(),getHeight(),
Config.ARGB_8888);
bitmap.eraseColor(((ColorDrawable) drawable).getColor());//填充颜色
else
bitmap = ((BitmapDrawable)drawable).getBitmap();
Bitmap roundBitmap = getRoundBitmap(bitmap, mCorner);
final Rect rectSrc = new Rect(0, 0, roundBitmap.getWidth(), roundBitmap.getHeight());
final Rect rectDest = new Rect(0,0,getWidth(),getHeight());
// 重置画笔,不然会留下黑色区域
mPaint.reset();
canvas.drawBitmap(roundBitmap, rectSrc, rectDest, mPaint);
else
super.onDraw(canvas);
/**
* 裁剪图片
* @param bitmap
* @param corner
* @return Bitmap
*/
private Bitmap getRoundBitmap(Bitmap bitmap, int corner)
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
bitmap.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final Rect rect = new Rect(getPaddingLeft(), getPaddingTop(), bitmap.getWidth()-getPaddingRight(), bitmap.getHeight()-getPaddingBottom());
final RectF rectF = new RectF(rect);
mPaint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
mPaint.setColor(Color.WHITE);
canvas.drawRoundRect(rectF, corner, corner, mPaint);
// 设置图像混合模式为SRC_IN,裁剪出我们的圆角Bitmap
mPaint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, mPaint);
return output;
/**
* dp转 px.
* @param value the value
* @return the int
*/
public static int dp2px(Context context, float value)
final float scale = context.getResources().getDisplayMetrics().densityDpi;
return (int) (value * (scale / 160) + 0.5f);
以上是关于Android自定义圆角矩形ImageView,支持Glide加载图片及颜色填充的主要内容,如果未能解决你的问题,请参考以下文章
Android学习笔记圆角矩形ImageView自定义控件的实现与使用
Android自定义圆角矩形ImageView,支持Glide加载图片及颜色填充