本章介紹了常用的 XML drawable,包括 shape,state list 和 layer list。還介紹了 9-patch 圖片和 mipmap 目錄等知識。
GitHub 地址:
完成第21章
1. XML drawable
在 Android 世界里,凡是要在屏幕上繪制的東西都可以叫作 drawable,比如抽象圖形、 Drawable 類的子類、位圖圖像等。我們之前用來封裝圖片的 BitmapDrawable 就是一種 drawable。 本章我們使用的 drawable 都定義在 XML 文件中,可以歸為一類,統(tǒng)稱為 XML drawable。
1.1 為什么要使用 XML drawable
XML drawable 用起來方便靈活,不僅用法多樣,還易于更新維護。搭配使用 shape drawable
和 layer list drawable 可以做出復(fù)雜的背景圖,連圖像編輯器都省了。更改應(yīng)用的配色更是簡單,直接修改 XML drawable 中的顏色就行了。
另外,XML drawable 獨立于屏幕像素密度,它們直接定義在 drawable 目錄中,不需要加屏幕密度資源修飾符。如果是普通圖像,就需要準備多個版本,以適配不同屏幕像素密度的設(shè)備;而 XML drawable 只要定義一次,就能在任何設(shè)備的屏幕上表現(xiàn)出色。
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 定義了一個帶有暗紅色圓環(huán)的填充紅色的橢圓。
- shape 標簽中 android:shape 屬性定義了其形狀為橢圓(當然,如果需要是正圓,只需要把控件的高寬設(shè)為相等即可),還可以是長方形,線條,梯形等圖形;
- solid 標簽定義填充,其中 android:color 定義其填充顏色(默認透明)
- stroke 標簽定義邊框,屬性都類似
- 還有更多標簽和屬性,可以在這里找到:shape drawable
1.3 state list drawable
為了在控件的不同狀態(tài)下切換不同的 drawable, 我們用到了 state list drawable,它會根據(jù)按鈕的狀態(tài)改變使用的 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,便是讓系統(tǒng)根據(jù)狀態(tài)選擇。狀態(tài)有按下,禁用,聚焦以及激活等狀態(tài),可以根據(jù)不同的狀態(tài)使用不同的 drawable。
還有更多標簽和屬性,可以在這里找到:state list drawable
1.4 layer list drawable
layer list 可以將多個 drawable 組成一個 drawable 并可以指定其擺放層次和位置,可以組成一些復(fù)雜的效果。
<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的網(wǎng)格,即由9 patch 組成的網(wǎng)格。網(wǎng)格角落部分不會被縮放,邊緣部分的4個 patch 只按一個維度縮放,而中間部分則按兩個維度縮放,如下圖:
9-patch 圖像和普通 PNG 圖像十分相似,只有兩處不同:9-patch 圖像文件名以.9.png 結(jié)尾,圖像邊緣具有1像素寬度的邊框。這個邊框用以指定9-patch 圖像的中間位置。邊框像素繪制為黑線, 以表明中間位置,邊緣部分則用透明色表示。
在 Android Studio 中,右鍵單擊想要轉(zhuǎn)換為 9-patch 的圖像文件選擇創(chuàng)建 9-patch 文件,然后雙擊打開,畫上黑邊即可。旁邊會顯示不同方向拉伸后的效果。
3. mipmap 目錄
應(yīng)用要用到圖像,就一般會針對不同的設(shè)備尺寸準備不同尺寸的圖片,再分別放入 drawable-mdpi 和 drawable-hdpi 這樣的文件夾。然后,按名字引用它們。 剩下的就交給 Android 了,它會根據(jù)當前設(shè)備的屏幕密度調(diào)用相應(yīng)的圖片。
這樣就會存在一個問題:發(fā)布出去的 APK 文件包含了項目 drawable 目錄里的所有圖片,哪怕是從來不會用到的圖片,這會讓應(yīng)用體積無意義地增大。為減輕負擔,有人想到針對設(shè)備定制 APK,比如 mdpi APK 一個,hdpi APK 一個,等等。有關(guān) APK 分包的詳細信息,可參閱Build Multiple APKs
相反,設(shè)置分包以后,有的時候會需要不同分辨率的圖標,比如啟動器不同,需要的圖標清晰度不同,所以,要用到 mipmap 目錄。APK 分包時,mipmap 資源會全部包含在 APK 文件中。
GitHub Page: kniost.github.io
簡書:http://www.lxweimin.com/u/723da691aa42