Android图片适配之——初探Image遮罩
什么是Image遮罩
android开发中不可缺少的就是各种图片的圆角,遮罩等等。
以前我都是用shape处理的,发现背景图的圆角要设置成和界面父元素背景一样才能看不出现纰漏。
当遇到背景多变的情况,比如listview隔行背景颜色不同的情况就郁闷了,又要加一堆代码处理。
现在有一个方法可以统一处理,就是用画布Canvas上添加Image遮罩。
实例
图片遮罩的一个常见应用就是在ImageView中显示位图之前,为其添加圆角。
让我们开始对图上的头像加上遮罩。
为了实现这一点,我们还是需要用到自定义控件,接收一张头像,使用BitmapShader将其作为圆角矩形绘制到Canvas中。(如果你对BitmapShader类并不了解,没有关系,我们接下来会单独聊聊)。
依旧还是自定义控件的老套路,我们这次继承了View在初始化方法init()中,创建了两个对象:paint与rectF。你可能会问了RectF类是什么?官方的Api解释我们就不说了留给自己百度,RectF类通俗一点可以理解为我们在View这张桌子上面放了一张白纸,而这张白纸的形状我们定义为矩形。
接下来我们当然是要开始测量布局啦!onMeasure方法中我们拿到mImage(就是我们的头像),获取了它的尺寸,然后通过getMeasurement()方法获取到我们需要的尺寸并设置给了View,这样View的尺寸算是确定了。你一定会问,getMeasurement()方法是什么?
方法接收了两个参数一个是onMeasure中的MeasureSpec(上一篇文章有详解)另一个是我们头像的尺寸。首先我们拿到View的尺寸,根据不同的度量模式我们返回不同的尺寸(View或者Image),比如我们在xml中将此View的尺寸写成固定值,则getMeasurement()方法会走最后一个case,直接返回View的尺寸,那么我们的View最终尺寸将会是xml中定义的尺寸。
完成了onMeasure方法View会立即回调onSizeChanged方法,因为onMeasure中我们设置了View的尺寸。onSizeChanged方法的四个参数分别记录了变化前与变化后View的尺寸,在onSizeChanged方法中我们主要完成4个任务:
1.获取头像的尺寸。
2.换算出头像的边距,目的让头像在View中处于居中位置。
3.设置rectF边界、大小。
4.给paint设置Matrix规则。
其中3、4任务比较难以理解,我们单独聊聊:
rectF.set()方法需要接收4个参数,很明显就是4个位置坐标,然后确定了rectF的大小。rectF.set()方法通俗理解就是我们在init方法中创建了一张矩形白纸,需要放置在View这张桌子上面,可是具体放置在什么位置呢?所以需要通过rectF.set()方法确定。
paint.getShader()我们一会再聊,Matrix类官方Api的描述我们就不重复了留给自己查看,这里我们用到Matrix类的setTranslate方法对平面进行平移。通俗的理解就是我在View这张桌子中从哪里开始绘制?默认(0,0)处,可是我们的rectF这张白纸的位置并不在默认(0,0)处,总不能画到View桌子上吧?所以setTranslate方法接收两个参数便是确定绘制的开始位置。最后把Matrix规则设置给paint。
万事俱备只欠东风,我们重写了最后一个方法onDraw,调用了drawRoundRect方法把我们的rectF纸,paint笔传入。drawRoundRect方法绘制一个矩形,而我们需要的是圆角矩形,所以继续传入半径100完成绘制。
最后我们需要对外界暴露一个方法接收我们的头像Bitmap:
这里我们用到了BitmapShader,位图渲染器,方法接收三个参数:
我们的头像Bitmap。
BitmapShader对超出边界绘制的处理模式,X方向。
BitmapShader对超出边界绘制的处理模式,Y方向。
最终给我们的画笔setShader设置渲染器便完成。
聊聊BitmapShader
Shader类包括了5个直接子类,分别为:BitmapShader、ComposeShader、LinearGradient、RadialGradient以及SweepGradient。其中,BitmapShader用于图像渲染;ComposeShader用于混合渲染;LinearGradient用于线性渲染;RadialGradient用于环形渲染;而SweepGradient则用于梯度渲染。
使用Shader类进行图像渲染时,首先需要构建Shader对象,然后通过Paint的setShader()方法来设置渲染对象,最后将这个Paint对象绘制到屏幕上即可。
通俗我们可以这么理解我们有一支笔Paint可是Paint并不知道需要绘制什么内容,所以我们需要一个BitmapShader图片渲染器里面告诉Paint需要绘制的图片与一些规则,比如TileMode.CLAMP模式,当rectF白纸大于我们的头像,那么空白的地方会被边缘拉伸至填充rectF。
结果
我们在布局文件中将View的尺寸写成了固定值,并设置了背景色为红色
红色部分是我们的View,在View居中位置我们绘制了圆角矩形遮罩rectF并在其上绘制了头像。
欢迎长按下图-识别图中二维码或者扫一扫关注我的公众号:
如果你有不同意见或建议或者有好的技术文章想和大家分享欢迎投稿,可以把你的文章使用附件的形式发送到我的邮箱2908116133@qq.com
谢谢阅读!
网友评论