简单实现圆形ImageView

两种方法实现CircleImageView

1、使用BitmapShader

: BitmapShader是Paint的5个渲染器之一,通过setShader (Shader shader)方法设置给Paint对象
我们看看BitmapShader的构造方法:
public BitmapShader (Bitmap bitmap, Shader.TileMode tileX, Shader.TileMode tileY)

在安卓api中这样解释道:

Call this to create a new shader that will draw with a bitmap.

说明这个BitmapShader是使用构造器中的bitmap作为内容,渲染效果就是 paint对象画过的区域变为bitmap的对应区域,你可以想想小时候那种笔写字了看不到,要用紫光还是什么光照到才可以看到那种效果,不过这里可以理解为,照到了就不会消失的,因为紫光(paint)走过了

这个我仅仅复制粘贴

static final Shader.TileMode CLAMP: 边缘拉伸.
static final Shader.TileMode MIRROR:在水平方向和垂直方向交替景象, 两个相邻图像间没有缝隙.
Static final Shader.TillMode REPETA:在水平方向和垂直方向重复摆放,两个相邻图像间有缝隙缝隙.

下面是代码:
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Shader;
import android.util.AttributeSet;
import android.widget.ImageView;

import com.xxhui.circleiamgeviewdemo.R;

/**
 * Created by xxhui on 2016/8/6.
 * 这个是通过bitmapShader实现
 */
public class CircleImageViewByBitmapShader extends ImageView {

    private int width;
    private int height;
    private int radius;

    public CircleImageViewByBitmapShader(Context context) {
        super(context);
    }

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

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        width = w;
        height = h;
        radius = Math.min(width, height) / 2;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        canvas.drawColor(Color.GREEN);//设置画布背景方便观察
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.photo);//夹在要画的图片,这里从资源文件,从其他地方也是可以的,比如sd卡
        BitmapShader bitmapShader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
        Paint paint = new Paint();
        paint.setAntiAlias(true);
        paint.setShader(bitmapShader);//给画笔设置渲染器,这里画笔画过的面积就是渲染器里面的图片
        canvas.drawCircle(width / 2, height / 2, radius, paint);//这里画一个实心圆,就是将实心圆大小的渲染器图片用画笔画在画布上,说的好抽象,自己加自己理解吧,这是我的理解
        //canvas.drawRect(0,0,width,height,paint);
    }
}

2、使用Xfermode

这个主角还是paint

我们通过setXfermode给paint设置一个Xfermode
这里用到一个类PorterDuffXfermode
这里来看看构造方法如何
public PorterDuffXfermode (PorterDuff.Mode mode)
那么我们就要了解一下PorterDuff.Mode,这里要了解两个基本的就是SRC和DST因为其他看意思就能推测出来啦,DST先画的部分,SRC后画的部分,听说常用的是DET_IN
和SRC_IN,我们看图解释一下这两个,其他也是差不多或者看图理解一下。
这里写图片描述
SRC_IN:因为是in,两个图形取交集, 取得到SRC(后画)的部分
DET_IN:取交集, 取得到DET(先画)的部分
说完基本知识了, 这里说说我的,基本思路(思路肯定很多的,自己实践的时候是什么就什么吧)
我这里我用到了SRC_IN,这就涉及到取交集了,先用一个canvas, 先画一个圆, 后画整张bitmap,取交集,得到bitmap的 后画部分,想想是不是圆形的bitmap?
得到了圆形的bitmap了,这个要真正放到ondraw方法的canvas上面,毕竟哪个canvas才是要显示的,哈哈哈,就到这里啦,上代码,看看设置Xfernode的时机!
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.util.AttributeSet;
import android.widget.ImageView;

import com.xxhui.circleiamgeviewdemo.R;

/**
 * Created by xxhui on 2016/8/6.
 */
public class CircleImageViewByXfermode extends ImageView {

    private int width;
    private int height;
    private int radius;

    public CircleImageViewByXfermode(Context context) {
        super(context);
    }

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

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        width = w;
        height = h;
        radius = Math.min(width, height) / 2;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.BLUE);//设置画布背景方便观察
        Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.photo);//夹在要画的图片,这里从资源文件,从其他地方也是可以的,比如sd卡
        Bitmap out = Bitmap.createBitmap(bitmap.getWidth(),bitmap.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas1 = new Canvas(out);

        Paint paint = new Paint();
        paint.setAntiAlias(true);
        canvas1.drawCircle(width/2,height/2,radius,paint);//画一个圆,辅助作用,应为这是先画的!
        //canvas1.drawCircle(0,0,radius,paint);//这个注视你可以尝试去掉,去掉你会发现,这是取先画的全部操作的并集,此时辅助区域变为这个并集
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));//DST先画,SRC后画,SRC_IN是取并集中属于后画的(有点拗口自己理解)
        canvas1.drawBitmap(bitmap,0,0,paint);//从这可以看出,先画(圆)和后画(bitmap)的交集为圆,而刚好圆属于整合bitmap,此时只画圆部分的bitmap,而不是整个bitmap
        canvas.drawBitmap(out,0,0,null);//最后只是简单的将一个为圆的bitmap画上去而已
        //canvas.drawBitmap(out,0,0,new Paint());//这个可以发现,其实只要不是带有Xfermode的画笔就可以了
    }
}

其实放入时机就是先画和后画中间

效果图:
这里写图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值