自定义圆形ImageView

时间:2022-07-06 20:34:49

网上资料已经很多了,这个是我自己写的,比较简洁一点。

来记一篇博客吧!

主要用到的知识:canvas啦bitmap啦paint啦这些都不说了,精华部分是Xfermode及PorterDuff的使用(虽然这里用得很少,但是作用很关键)。Xfermode及PorterDuff的详细介绍,可以参见我上一篇博客:Android颜色渲染:PorterDuff及Xfermode详解


梳理一下实现过程吧:

1.首先继承ImageView

2.获取本控件尺寸

3.根据控件尺寸内切一个圆形的bitmap出来

4.绘制

4.1 取出设置的图片资源,绘制到含有新的画布上。

4.2 设置画笔的渲染模式,让它只显示两图层的交集处的底层内容,继续绘制圆形的bitmap,此时它在图片的上一层,所以就切出了圆形ImageView效果


然后,以下是代码和资源,代码注释比较完善了,有误之处,谢谢指正!

package com.cc.library.view;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ImageView;

/**
* 圆形imageview
* 基本原理,图层上第一层放矩形图片,往上第二层放一个圆形的位图(bitmap),
* 利用PorterDuffXfermode设置渲染模式,只绘制两图层的交集并显示下一图层的内容
* 最终的效果就是一个被切出一个圆形的imageview效果
* Created by zhangyu on 2016-07-07 14:17.
*/
public class RoundImageView extends ImageView {

private static final String TAG = "RoundImageView";
private PorterDuffXfermode porterDuffXFermode;//颜色渲染模式
//控件宽、高
private int viewWidth, viewHeight;
private Paint paint;

public RoundImageView(Context context) {
super(context);
init();
}

public RoundImageView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}

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

private void init() {
paint = new Paint();
paint.setAntiAlias(true);

porterDuffXFermode = new PorterDuffXfermode(PorterDuff.Mode.DST_IN);//取两层绘制交集,显示下层。
}

@Override
protected void onDraw(Canvas canvas) {
Drawable drawable = getDrawable();
Bitmap bitmap = Bitmap.createBitmap(viewWidth, viewHeight, Bitmap.Config.ARGB_8888);//创建一个与控件尺寸相同的基本位图
Bitmap roundBitmap = getRoundBitmap();//圆形位图

Canvas drawCanvas = new Canvas(bitmap);//创建一个用于绘制内容的画布

drawable.setBounds(0, 0, viewWidth, viewHeight);//设置drawable绘制区域
drawable.draw(drawCanvas);//将所设置的图片绘制到画布上(第一层)

paint.setFilterBitmap(false);
paint.setXfermode(porterDuffXFermode);
drawCanvas.drawBitmap(roundBitmap, 0, 0, paint);//将圆形位图绘制到画布上(第二层)

paint.setXfermode(null);
canvas.drawBitmap(bitmap, 0, 0, paint);//将drawCanvas上绘制好的位图(已经有两层内容并按渲染模式绘制)绘制到控件画布上
}

/**
* 获取一个圆形的bitmap 大小内切image尺寸矩形
* @return
*/
private Bitmap getRoundBitmap() {
Bitmap bitmap = Bitmap.createBitmap(viewWidth, viewHeight, Bitmap.Config.ARGB_8888);
Canvas roundCanvas = new Canvas(bitmap);

int raidus = Math.min(viewHeight, viewWidth) / 2;
roundCanvas.drawCircle(viewWidth / 2, viewHeight / 2, raidus, new Paint());

return bitmap;
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
viewWidth = getMeasuredWidth();
viewHeight = getMeasuredHeight();
Log.d(TAG, "onMeasure viewWidth = " + viewWidth + " ,viewHeight = " + viewHeight);
}
}

资源下载地址: http://download.csdn.net/detail/chen_zhang_yu/9570025

谢谢支持!自定义圆形ImageView希望对大家有用!