天天看點

Android程式設計權威指南(第二版)學習筆記(二十一)—— 第21章 XML drawable1. XML drawable2. 9-patch 圖像(九宮格圖像)3. mipmap 目錄

本章介紹了常用的 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 隻按一個次元縮放,而中間部分則按兩個次元縮放,如下圖:

Android程式設計權威指南(第二版)學習筆記(二十一)—— 第21章 XML drawable1. XML drawable2. 9-patch 圖像(九宮格圖像)3. mipmap 目錄

9-patch 圖像和普通 PNG 圖像十分相似,隻有兩處不同:9-patch 圖像檔案名以.9.png 結尾,圖像邊緣具有1像素寬度的邊框。這個邊框用以指定9-patch 圖像的中間位置。邊框像素繪制為黑線, 以表明中間位置,邊緣部分則用透明色表示。

在 Android Studio 中,右鍵單擊想要轉換為 9-patch 的圖像檔案選擇建立 9-patch 檔案,然後輕按兩下打開,畫上黑邊即可。旁邊會顯示不同方向拉伸後的效果。

Android程式設計權威指南(第二版)學習筆記(二十一)—— 第21章 XML drawable1. XML drawable2. 9-patch 圖像(九宮格圖像)3. mipmap 目錄

3. mipmap 目錄

應用要用到圖像,就一般會針對不同的裝置尺寸準備不同尺寸的圖檔,再分别放入 drawable-mdpi 和 drawable-hdpi 這樣的檔案夾。然後,按名字引用它們。 剩下的就交給 Android 了,它會根據目前裝置的螢幕密度調用相應的圖檔。

這樣就會存在一個問題:釋出出去的 APK 檔案包含了項目 drawable 目錄裡的所有圖檔,哪怕是從來不會用到的圖檔,這會讓應用體積無意義地增大。為減輕負擔,有人想到針對裝置定制 APK,比如 mdpi APK 一個,hdpi APK 一個,等等。有關 APK 分包的詳細資訊,可參閱Build Multiple APKs

相反,設定分包以後,有的時候會需要不同分辨率的圖示,比如啟動器不同,需要的圖示清晰度不同,是以,要用到 mipmap 目錄。APK 分包時,mipmap 資源會全部包含在 APK 檔案中。