Android自定义ImageView(中)之圆形圆角矩形ImageView

[TOC]

概述

这是一个可以设置成圆角或者圆角矩形的ImageView,并且可以设置是否支持多点触控放大,缩小,旋转图片,双击放大缩小的自定义的控件。还有一个仿刮刮卡效果的自定义View。

效果展示

效果展示
录制的视频5.4M,可能打不开得下下来看。

相关知识点

上一次我们讲了:Android自定义ImageView(上)之多点触控放大缩小,双击放大缩小
这回,我们在来唠唠:怎么实现圆形或者圆角矩形的Imageiew。让ImageView显示一张圆形图片的方法有很多:让UI切一个,用第三方图片加载框架,直接在xml中设置ImageView控件的形状。这些都可以做到,但是我们需要的是更强大的,扩展性更强的方式。需要不管是什么样的图片,放到控件里面都会变成圆形,圆角矩形,甚至是三角形,五角星等等可定制的控件。嗯,这篇文章讲的就是这样的ImageView。

额,装X好累。直接开始吧。

关键代码和注意事项

思路

1.获取ImageView的图片资源,创建一个Canvas画一个你想要的形状

    /**
     * 获取圆形图片方法
     *
     * @param bitmap
     * @return Bitmap
     * @author caizhiming
     */
    private Bitmap getCircleBitmap(Bitmap bitmap) {
        Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(output);
//将output作为canvas的操作对象
        canvas.drawCircle(getMatrixRectF().centerX(), getMatrixRectF().centerY(), Math.min(output.getWidth(), output.getHeight()) / 2, paint);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(bitmap, matrix, paint);
        return output;
    }

    /**
     * 获取圆角矩形图片
     */
    private Bitmap getBoundsBitmap(Bitmap bitmap, int radius) {
        Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(output);
//将output作为canvas的操作对象
        canvas.drawRoundRect(getMatrixRectF(), radius, radius, paint);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(bitmap, matrix, paint);
        return output;
    }
    /**
     * 在代码中设置图片调用这个,在xml设置图片不调用这个方法
     * @param drawable
     */
    @Override
    public void setImageDrawable(@Nullable Drawable drawable) {
        super.setImageDrawable(drawable);
        if (isCircle) {
            isBounds = false;
            Bitmap bitmap = ((BitmapDrawable) getDrawable()).getBitmap();
            paint = new Paint();
            outBitmap = getCircleBitmap(bitmap);
            postInvalidate();
        }
        if (isBounds) {
            isCircle = false;
            Bitmap bitmap = ((BitmapDrawable) getDrawable()).getBitmap();
            paint = new Paint();
            outBitmap = getBoundsBitmap(bitmap, radius);
            postInvalidate();
        }
    }

这里面有一个小坑,就是如果在代码中设置图片,那么 ((BitmapDrawable) getDrawable()).getBitmap();是取不到图片的,得重写setImageDrawable()方法,同理,如果在xml中设置了图片,那么是不会执行setImageDrawable()方法,所以获取图片资源的方法两个地方都要写。

2.用Xfermode的(src_in)属性的paint在ondraw()中把bitmap画出来
android.graphics.PorterDuff.Mode.SRC_IN:只在源图像和目标图像相交的地方绘制源图像

    @Override
    protected void onDraw(Canvas canvas) {
        paint.reset();
        canvas.drawBitmap(outBitmap, matrix, paint);
    }

这里注意重置一下画笔,就这样就完成了,是不是很简单

总结

不知大家发现没有,我们getCircleBitmap()方法中的Canvas对象CA和ondraw()的canvas对象CB不一样啊。而且ondraw()的canvas画的貌似只是一个空白的bitmap而已啊,怎么会这样呢。

请注意我们实例化我们getCircleBitmap()方法中的Canvas对象时传入的参数 Canvas canvas = new Canvas(output);这个output就是ondraw()中的canvas所画的那个bitmap,这说明getCircleBitmap()中canvas所做的所有的操作都会作用在output上。

还要注意一点canvas不能直接操作资源文件,不然会报错。

项目地址链接

github项目地址

个人公众号

《Android自定义ImageView(中)之圆形圆角矩形ImageView》

不只是技术文章哦,快关注我吧。
搜索公众号:kedasay

    原文作者:badc59a1a8c4
    原文地址: https://www.jianshu.com/p/036d64cb0736
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞