一个简单的多功能自定义圆角ImageView

之前为了图方便和赶工期,所以直接使用早期的工具类去裁剪。后期的话有一些时间,所以做了一些优化,就自定义了一个圆角ImageView。其实大概思路都是清楚的,但是想看下网上有没有其他好的方便的,结果一查,跟我的思路基本一样,就是在onDrawable中做裁剪,但是代码一大推,也是醉了。后面看到一个挺有意思的思路,是通过clipPath实现的。

使用裁剪的代码:

//RoundedBitmapDrawable是基于glide的
public static Drawable bitmapToRound(Context context, Bitmap bitmap, int resid) {
    if (bitmap != null) {
        int radius = 0;
        try {
            radius = context.getResources().getDimensionPixelOffset(resid);

            RoundedBitmapDrawable circularBitmapDrawable =
                    RoundedBitmapDrawableFactory.create(context.getResources(), bitmap);
            circularBitmapDrawable.setCornerRadius(radius); //设置圆角弧度
            return circularBitmapDrawable;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return drawableToRound(context, new BitmapDrawable(bitmap), radius);
    }

    return null;
}

自定义ImageView核心代码:

@Override
protected void onDraw(Canvas canvas) {
     if (mLeftTopRadius > 0 || mLeftBottomRadius > 0
             || mRightTopRadius > 0 || mRightBottomRadius > 0) {
         try {
             Drawable drawable = getDrawable();
             int w = this.getWidth();
             int h = this.getHeight();
//                LogUtils.d(drawable + " " + w + " " + h);
             if (null != drawable /*&& drawable instanceof BitmapDrawable*/
                     && w > 0 && h > 0) {
                 //https://www.cnblogs.com/zhujiabin/p/7403753.html
                 //https://cloud.tencent.com/developer/article/1331001
                 Path path = new Path();
                 /*圆角的半径,依次为左上角xy半径,右上角,右下角,左下角*/
                 float[] rids = {mLeftTopRadius, mLeftTopRadius, mRightTopRadius, mRightTopRadius, mRightBottomRadius, mRightBottomRadius, mLeftBottomRadius, mLeftBottomRadius};
                 path.addRoundRect(new RectF(0, 0, w, h), rids, Path.Direction.CW);
                 canvas.clipPath(path);
             }
         } catch (Exception e) {
             e.printStackTrace();
         }
     }
     super.onDraw(canvas);
 }

上图中,我自定义了四个角,所以其实是可以实现单独设置的。
但是,这里有一个问题,就是这块只能修改ImageViewsrc图片,并不能让Background也是圆角。
这个问题是因为,当执行onDraw时,Background早已经在draw中绘制了(View.draw.drawBackground),故我们如果想让Background也是圆角,可以在draw方法中实现

@Override
public void draw(Canvas canvas) {
    if (mLeftTopRadius > 0 || mLeftBottomRadius > 0
            || mRightTopRadius > 0 || mRightBottomRadius > 0) {
        try {
            Drawable drawable = getDrawable();
            int w = this.getWidth();
            int h = this.getHeight();
//                LogUtils.d(drawable + " " + w + " " + h);
            if (null != drawable /*&& drawable instanceof BitmapDrawable*/
                    && w > 0 && h > 0) {
                //https://www.cnblogs.com/zhujiabin/p/7403753.html
                //https://cloud.tencent.com/developer/article/1331001
                Path path = new Path();
                /*圆角的半径,依次为左上角xy半径,右上角,右下角,左下角*/
                float[] rids = {mLeftTopRadius, mLeftTopRadius, mRightTopRadius, mRightTopRadius, mRightBottomRadius, mRightBottomRadius, mLeftBottomRadius, mLeftBottomRadius};
                path.addRoundRect(new RectF(0, 0, w, h), rids, Path.Direction.CW);
                canvas.clipPath(path);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    super.draw(canvas);
}

对了,切记使用clipPath针对的是画布canvas,不是针对图片。所如果你的图片(不管是srcBackground),如果跟绘制面积比画布小,是不会有圆角效果的。

源码下载,欢迎Start

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值