领略千变万化的Android Drawable (一)

Android Drawable 相信大家都不陌生,本篇我们就来全面深入了解它,Drawable是一种可以在Canvas上进行绘制的抽象的图像,它的子类也相当多,所以在开发中很容易导致我们对不同Drawable的理解产生混乱,因此我们很有必要来全面了解一下Drawable的子类及其使用方式滴,哈~。

一、Drawable的简述

Drawable在我们开发中常被用来作为View的背景图像,一般情况下我们都是通过XML来定义Drawable的,当然我们也可以通过代码创建Drawable,只不过会比较复杂而已。Drawable最大的好处就是可以方便我们做出一些特殊的UI效果,这点比我们自定义View实现的效果来得更容易些。因此深入理解Drawable的用法还是很有必要的,接下来我们来看看Drawable的一些特性:

  • 1、Drawable本身表示的只是一种图像的概念,因此Drawable不仅仅是图片,也可以是颜色构造出来的图像效果(后面会说明)。
  • 2、Drawable本身是一个抽象类,因此具体的实现都是由子类完成的,比如ShapeDrawable,BitmapDrawable等。
  • 3、Drawable的内部宽高可以分别通过getIntrinsicWidth()和getIntrinsicHeight()获取,但并不是所有的Drawable都有内部宽高的属性,比如一个颜色形成的Drawable并没有宽高的概念。在大多数情况下,Drawable并没有大小的概念,因为当Drawable作为View的背景图时,Drawable会被拉伸至View的同等大小。

二、千变万化的Drawable

1、BitmapDrawable

BitmapDrawable 是对bitmap的一种包装,可以设置它包装的bitmap在BitmapDrawable区域内的绘制方式,如平铺填充、拉伸填充或者保持图片原始大小,也可以在BitmapDrawable区域内部使用gravity指定的对齐方式。其语法如下:

我们分析一下这些属性的含义:

android:src

类型:Drawable resource。必需。 引用一个drawable resource.

android:antialias

类型:Boolean。是否开启抗锯齿。开启后图片会变得更平滑些,因此一般建议开启,设置为true即可。

android:dither

类型:Boolean。是否允许抖动,如果位图与屏幕的像素配置不同时,开启这个选项可以让高质量的图片在低质量的屏幕上保持较好的显示效果(例如:一个位图的像素设置是 ARGB 8888,但屏幕的设置是RGB 565,开启这个选项可以是图片不过于失真)一般建议开启,为true即可。

android:filter

类型:Boolean。是否允许对位图进行滤波。当图片被压缩或者拉伸时,使用滤波可以获得平滑的外观效果。一般建议开启,为true即可

android:gravity

当图片小于容器尺寸时,设置此选项可以对图片经典定位,这个属性比较多,不同选项可以使用‘|’来组合使用。

可选项 含义
top 将图片放在容器顶部,不改变图片大小
bottom 将图片放在容器底部,不改变图片大小
left 将图片放在容器左侧,不改变图片大小
right 将图片放在容器右侧,不改变图片大小
center_vertical 图片竖直居中,不改变图片大小
fill_vertical 图片竖直方向填充容器
center_horizontal 图片水平居中,不改变图片大小
fill_horizontal 图片水平方向填充容器
center 使图片在水平方向和竖直方向同时居中,不改变图片大小
fill 图片填充容器,默认值
clip_vertical 竖直方向剪切,很少使用
clip_horizontal 水平方向剪切,很少使用

android:mipMap

纹理映射处理技术,不太懂,不过一般也不用,默认为false

android:tileMode

平铺模式。共有以下几个值
disabled :默认值,表示不使用平铺
clamp :复制边缘色彩
repeat :X、Y 轴进行重复图片显示,也就是我们说要说的平铺
mirror :在水平和垂直方向上使用交替镜像的方式重复图片的绘制

三者区别如下图:

BitmapDrawable的xml使用方式比较简单,我们这里就不贴案例了哈。接下来我们来看看在代码中如何使用BitmapDrawable。


实际上我们从BitmapDrawable的源码可以看出,目前Google建议我们创建BitmapDrawable的构造方法有3种

参数比较简单,res就是我们通过getResource()获取到的资源管理对象,bitmap就是我们需要用BitmapDrawable包装的图片对象,filepath,需要包装的图片所在路径,is则是一个图像流,需要转换成 BitmapDrawable。但是在大多数情况下我们还是建议使用xml实现比较好,代码实现我们不打算深究,我们这里直接给出一个代码应用案例:

2、NinePatchDrawable

NinePatchDrawable表示的是我们熟悉的.9格式的图片,.9图片可以在保证图片不失真的情况下任意进行缩放,在实际的使用中我们也是通过Xml来实现即可:

属性和BitmapDrawable中属性的含义相同,这里不过多描述。一般情况下不建议代码创建.9图,因为Android虽然可以使用Java代码创建NinePatchDrawable,但是极少情况会那么做,这是因为由于Android SDK会在编译工程时对点九图片进行编译,形成特殊格式的图片。使用代码创建NinePatchDrawable时只能针对编译过的点九图片资源,对于没有编译过的点九图片资源都当做BitmapDrawable对待。还有点需要特别注意的是,点九图只能适用于拉伸的情况,对于压缩的情况并不适用,如果需要适配很多分辨率的屏幕时需要把点九图做的小一点。

3、ShapeDrawable

ShapeDrawable对于Xml的shape标签,在实际开发中我们经常将其作为背景图片使用,因为ShapeDrawable可以帮助我们通过颜色来构造图片,也可以构造渐变效果的图片,总之,ShapeDrawable足矣满足我们大部分特殊需求下面我们说说其使用方法: