本章介绍了常用的 XML drawable,包括 shape,state list 和 layer list。还介绍了 9-patch 图片和 mipmap 目录等知识。
GitHub 地址:
完成第21章
1. XML drawable
在 Android 世界里,凡是要在屏幕上绘制的东西都可以叫作 drawable,比如抽象图形、 Drawable 类的子类、位图图像等。我们之前用来封装图片的 BitmapDrawable 就是一种 drawable。 本章我们使用的 drawable 都定义在 XML 文件中,可以归为一类,统称为 XML drawable。
1.1 为什么要使用 XML drawable
XML drawable 用起来方便灵活,不仅用法多样,还易于更新维护。搭配使用 shape drawable
和 layer list drawable 可以做出复杂的背景图,连图像编辑器都省了。更改应用的配色更是简单,直接修改 XML drawable 中的颜色就行了。
另外,XML drawable 独立于屏幕像素密度,它们直接定义在 drawable 目录中,不需要加屏幕密度资源修饰符。如果是普通图像,就需要准备多个版本,以适配不同屏幕像素密度的设备;而 XML drawable 只要定义一次,就能在任何设备的屏幕上表现出色。
1.2 shape drawable
一个常见的圆形 shape drawable 如下:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<solid
android:color="@color/red"/>
<stroke
android:width="4dp"
android:color="@color/dark_red"/>
</shape>
该 shape drawable 定义了一个带有暗红色圆环的填充红色的椭圆。
- shape 标签中 android:shape 属性定义了其形状为椭圆(当然,如果需要是正圆,只需要把控件的高宽设为相等即可),还可以是长方形,线条,梯形等图形;
- solid 标签定义填充,其中 android:color 定义其填充颜色(默认透明)
- stroke 标签定义边框,属性都类似
- 还有更多标签和属性,可以在这里找到:shape drawable
1.3 state list drawable
为了在控件的不同状态下切换不同的 drawable, 我们用到了 state list drawable,它会根据按钮的状态改变使用的 drawable,一个例子如下:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/button_beat_box_pressed"
android:state_pressed="true"/>
<item android:drawable="@drawable/button_beat_box_normal"/>
</selector>
将一个 drawable 资源文件定义为 selector,便是让系统根据状态选择。状态有按下,禁用,聚焦以及激活等状态,可以根据不同的状态使用不同的 drawable。
还有更多标签和属性,可以在这里找到:state list drawable
1.4 layer list drawable
layer list 可以将多个 drawable 组成一个 drawable 并可以指定其摆放层次和位置,可以组成一些复杂的效果。
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="oval">
<solid
android:color="@color/red"/>
</shape>
</item>
<item>
<shape android:shape="rectangle">
<stroke
android:width="4dp"
android:color="@color/dark_red"/>
</shape>
</item>
</layer-list>
这个 layer list 将一个矩形叠放在一个椭圆上。还有更多的属性可以查看 layer list drawable
2. 9-patch 图像(九宫格图像)
有时候,按钮背景图必须用到普通图片。那么,如果按钮需要以不同尺寸显示,背景图该如何变化呢?如果按钮的宽度大于背景图的宽度,图片会被拉伸。拉伸的图片会有很好的效果吗? 朝一个方向拉伸背景图很可能会让图片失去原样,所以得想个办法控制图片拉伸方式。
9-patch 就是这样一种方式,它将图像分成3×3的网格,即由9 patch 组成的网格。网格角落部分不会被缩放,边缘部分的4个 patch 只按一个维度缩放,而中间部分则按两个维度缩放,如下图:
9-patch 图像和普通 PNG 图像十分相似,只有两处不同:9-patch 图像文件名以.9.png 结尾,图像边缘具有1像素宽度的边框。这个边框用以指定9-patch 图像的中间位置。边框像素绘制为黑线, 以表明中间位置,边缘部分则用透明色表示。
在 Android Studio 中,右键单击想要转换为 9-patch 的图像文件选择创建 9-patch 文件,然后双击打开,画上黑边即可。旁边会显示不同方向拉伸后的效果。
3. mipmap 目录
应用要用到图像,就一般会针对不同的设备尺寸准备不同尺寸的图片,再分别放入 drawable-mdpi 和 drawable-hdpi 这样的文件夹。然后,按名字引用它们。 剩下的就交给 Android 了,它会根据当前设备的屏幕密度调用相应的图片。
这样就会存在一个问题:发布出去的 APK 文件包含了项目 drawable 目录里的所有图片,哪怕是从来不会用到的图片,这会让应用体积无意义地增大。为减轻负担,有人想到针对设备定制 APK,比如 mdpi APK 一个,hdpi APK 一个,等等。有关 APK 分包的详细信息,可参阅Build Multiple APKs
相反,设置分包以后,有的时候会需要不同分辨率的图标,比如启动器不同,需要的图标清晰度不同,所以,要用到 mipmap 目录。APK 分包时,mipmap 资源会全部包含在 APK 文件中。
GitHub Page: kniost.github.io
简书:http://www.jianshu.com/u/723da691aa42