美文网首页Android小坑Android知识Android技术知识
Android自定义ImageView(中)之圆形圆角矩形Ima

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

作者: badc59a1a8c4 | 来源:发表于2017-11-03 23:47 被阅读115次

    [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项目地址

    个人公众号


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

    相关文章

      网友评论

        本文标题:Android自定义ImageView(中)之圆形圆角矩形Ima

        本文链接:https://www.haomeiwen.com/subject/bxvxmxtx.html