Android可繪製物件資源之shape和layer-list使用

Code4Android發表於2017-04-20

前言

文章中內容多來自谷歌官方文件詳戳,一些示例程式碼詳戳GitHub,不喜請輕噴。

可繪製物件資源

可繪製物件資源是一般概念,是指可在螢幕上繪製的圖形,以及可以使用 getDrawable(int) 等 API 檢索或者應用到具有 android:drawable 和 android:icon 等屬性的其他 XML 資源的圖形。共有多種不同型別的可繪製物件:

  • 點陣圖檔案
    點陣圖圖形檔案(.png、.jpg 或 .gif)。建立 BitmapDrawable。
  • 九宮格檔案
    具有可拉伸區域的 PNG 檔案,允許根據內容調整影象大小 (.9.png)。建立 NinePatchDrawable。
  • 圖層列表
    管理其他可繪製物件陣列的可繪製物件。它們按陣列順序繪製,因此索引最大的元素繪製在頂部。建立 LayerDrawable。
  • 狀態列表
    此 XML 檔案為不同狀態引用不同點陣圖圖形(例如,按下按鈕時使用不同的影象)。建立 StateListDrawable。
  • 級別列表
    此 XML 檔案用於定義管理大量備選可繪製物件的可繪製物件,每個可繪製物件都分配有最大的備選數量。建立 LevelListDrawable。
  • 轉換可繪製物件
    此 XML 檔案用於定義可在兩種可繪製物件資源之間交錯淡出的可繪製物件。建立 TransitionDrawable。
  • 插入可繪製物件
    此 XML 檔案用於定義以指定距離插入其他可繪製物件的可繪製物件。當檢視需0要小於檢視實際邊界的背景可繪製物件時,此類可繪製物件很有用。
  • 裁剪可繪製物件
    此 XML 檔案用於定義對其他可繪製物件進行裁剪(根據其當前級別值)的可繪製物件。建立 ClipDrawable。
  • 縮放可繪製物件
    此 XML 檔案用於定義更改其他可繪製物件大小(根據其當前級別值)的可繪製物件。建立 ScaleDrawable
  • 形狀可繪製物件
    此 XML 檔案用於定義幾何形狀(包括顏色和漸變)。建立 ShapeDrawable。
    另請參閱動畫資源文件,瞭解如何建立 AnimationDrawable。

注:顏色資源也可用作 XML 中的可繪製物件。例如,在建立狀態列表可繪製物件時,可以引用 android:drawable 屬性的顏色資源 (android:drawable="@color/green")

shape

shape顧名思義就是形狀的意思,在我們平時的開發中,應用的頻率也很高,該檔案是一個xml檔案,並放在drawale資料夾下如res/drawable/filename.xml, 那麼引用方式也很簡單了,我們一般在控制元件的background使用,如android:background="@drawable/filename"。所有屬性如下

<?xml version="1.0" encoding="utf-8"?>
<!--   shape必須為根元素
xmlns:名稱空間
android:shape指定形狀型別
    rectangle:填充包含檢視的矩形,當不寫該屬性時預設此形狀
    oval:橢圓形狀
    line:線形狀,此形狀需要 <stroke> 元素定義線寬
    ring:環形
當android:shape="ring"時,有可選屬性
        android:innerRadius:尺寸。環內部(中間的孔)的半徑
        android:innerRadiusRatio:浮點型。環內部的半徑,以環寬度的比率表示。例如,如果 android:innerRadiusRatio="5",則內半徑等於環寬度除以 5。此值被 android:innerRadius 覆蓋。預設值為 9。
        android:thickness:環的厚度
        android:thicknessRatio:浮點型。環的厚度,表示為環寬度的比率。例如,如果 android:thicknessRatio="2",則厚度等於環寬度除以 2。此值被 android:innerRadius 覆蓋。預設值為 3。
    需要注意的是,如果你使用了上面幾個屬性繪製一個圓,會發現在控制元件中並沒有效果,我們還需要一個重要屬性
        android:useLevel:布林值。如果這用作 LevelListDrawable,則此值為“true”。這通常應為“false”,否則形狀不會顯示。
 -->
<shape
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape=["rectangle" | "oval" | "line" | "ring"] >
    <!--
    corners為形狀產生圓角,僅當形狀為矩形時使用
        android:radius:尺寸。所有角的半徑,以尺寸值或尺寸資源表示。對於每個角,這會被以下屬性覆蓋。
        android:topLeftRadius:左上角的半徑,以尺寸值或尺寸資源表示。
        android:topRightRadius:右上角的半徑,以尺寸值或尺寸資源表示。
        android:bottomLeftRadius:左下角的半徑,以尺寸值或尺寸資源表示。
        android:bottomRightRadius:右下角的半徑,以尺寸值或尺寸資源表示
    -->
    <corners
        android:radius="integer"
        android:topLeftRadius="integer"
        android:topRightRadius="integer"
        android:bottomLeftRadius="integer"
        android:bottomRightRadius="integer" />
    <!--
        指定形狀的漸變顏色,使用漸變時不要使用solid,否則會被覆蓋,看不到效果
        android:angle:整型。漸變的角度(度)。0 為從左到右,90 為從上到上。必須是 45 的倍數。預設值為 0,如果寫該值不是45的整數倍,將沒有效果。
        android:centerX:浮點型。漸變中心的相對 X 軸位置 (0 - 1.0)。
        android:centerY:浮點型。漸變中心的相對 Y 軸位置 (0 - 1.0)。
        android:centerColor:顏色。起始顏色與結束顏色之間的可選顏色,以十六進位制值或顏色資源表示。
        android:endColor:顏色。結束顏色,表示為十六進位制值或顏色資源。
        android:gradientRadius:浮點型。漸變的半徑。僅在 android:type="radial" 時適用。且radial時必須有該屬性,否則無效果
        android:startColor:顏色。起始顏色,表示為十六進位制值或顏色資源。
        android:type:要應用的漸變圖案的型別。有效值為
                      "linear"    線性漸變。這是預設值。
                      "radial"    徑向漸變。起始顏色為中心顏色。
                      "sweep"    流線型漸變。
        android:useLevel:布林值。如果這用作 LevelListDrawable,則此值為“true”。
    -->
    <gradient
        android:angle="integer"
        android:centerX="float"
        android:centerY="float"
        android:centerColor="integer"
        android:endColor="color"
        android:gradientRadius="integer"
        android:startColor="color"
        android:type=["linear" | "radial" | "sweep"]
        android:useLevel=["true" | "false"] />
    <!--
        要應用到包含檢視元素的內邊距(這會填充檢視內容的位置,而非形狀)。
        android:left:尺寸。左內邊距,表示為尺寸值或尺寸資源
        android:top:尺寸。上內邊距,表示為尺寸值或尺寸資源
        android:right:尺寸。右內邊距,表示為尺寸值或尺寸資源
        android:bottom:尺寸。下內邊距,表示為尺寸值或尺寸資源
    -->
    <padding
        android:left="integer"
        android:top="integer"
        android:right="integer"
        android:bottom="integer" />
    <!--
        指定形狀的大小
        注:預設情況下,形狀按照此處定義的尺寸按比例縮放至容器檢視的大小。在 ImageView 中使用形狀時,可通過將 android:scaleType 設定為 "center" 來限制縮放。
    -->
    <size
        android:width="integer"
        android:height="integer" />
    <!---
        用於填充形狀的顏色
        android:color:顏色。應用於形狀的顏色
        ->
    <solid
        android:color="color" />
    <!--
        形狀的筆劃中線。即形狀的邊框
        android:width:尺寸。線寬,以尺寸值或尺寸資源表示。
        android:color:顏色。線的顏色,表示為十六進位制值或顏色資源。
        android:dashGap:尺寸。短劃線的間距,以尺寸值或尺寸資源表示。僅在設定了 android:dashWidth 時有效。
        android:dashWidth:尺寸。每個短劃線的大小,以尺寸值或尺寸資源表示。僅在設定了 android:dashGap 時有效。
-->
    <stroke
        android:width="integer"
        android:color="color"
        android:dashWidth="integer"
        android:dashGap="integer" />
</shape>複製程式碼

簡單效果圖

Android可繪製物件資源之shape和layer-list使用
這裡寫圖片描述

xml實現檔案:

<?xml version="1.0" encoding="utf-8"?><!--    -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <corners
        android:radius="15dp"
        android:topLeftRadius="3dp" />
    <gradient
        android:centerColor="#00ff00"
        android:centerX="0.5"
        android:centerY="0.5"
        android:endColor="#0000ff"
        android:gradientRadius="25dp"
        android:startColor="#ff0000"
        android:type="radial" />
    <!--    <solid
            android:color="#00ff00"/>-->
    <size
        android:width="10dp"
        android:height="10dp" />
    <padding
        android:bottom="15dp"
        android:left="15dp"
        android:right="15dp"
        android:top="15dp" />

</shape>複製程式碼

在xml檔案實現shape和用java程式碼實現大同小異,他們命名規則都是相對應的,可參照官方API文件,戳此連結檢視

圖層列表layer-list

LayerDrawable 是管理其他可繪製物件陣列的可繪製物件。列表中的每個可繪製物件按照列表的順序繪製,列表中的最後一個可繪製物件繪於頂部。每個可繪製物件由單一 元素內的 元素表示。我們需要注意的是layer-list中有item的先後順序會影響展示效果,不同順序的效果可能大相徑庭,因為,後面的item總是在之前的item之上並覆蓋顯示。

<?xml version="1.0" encoding="utf-8"?>
<!-- 
必備。這必須是根元素。包含一個或多個 <item> 元素。
xmlns:android:字串。必備。定義 XML 名稱空間,其必須是 "http://schemas.android.com/apk/res/android"。
-->
<layer-list
    xmlns:android="http://schemas.android.com/apk/res/android" >
    <!--
    定義要放在圖層可繪製物件中由其屬性定義的位置的可繪製物件。必須是 <selector> 元素的子項。接受子 <bitmap> 元素。
    android:drawable:可繪製物件資源。必備。引用可繪製物件資源。
    android:id:資源 ID。此可繪製物件的唯一資源 ID。要為此項新建資源 ID,請使用以下形式:"@+id/name"。加號表示應建立為新 ID。可以使用此 ID 檢索和修改具有 View.findViewById() 或 Activity.findViewById() 的可繪製物件。
    android:top:整型。頂部偏移(畫素)。
    android:right:整型。右邊偏移(畫素)。
    android:bottom:整型。底部偏移(畫素)。
    android:left:整型。左邊偏移(畫素)。
    -->
    <item
        android:drawable="@[package:]drawable/drawable_resource"
        android:id="@[+][package:]id/resource_name"
        android:top="dimension"
        android:right="dimension"
        android:bottom="dimension"
        android:left="dimension" />
</layer-list>複製程式碼

預設情況下,所有可繪製項都會縮放以適應包含檢視的大小。因此,將影象放在圖層列表中的不同位置可能會增大檢視的大小,並且有些影象會相應地縮放。為避免縮放列表中的專案,請在 元素內使用 元素指定可繪製物件,並且對某些不縮放的專案(例如 "center")定義重力。例如,以下 定義縮放以適應其容器檢視的專案:


為避免縮放,以下示例使用重力居中的 元素:

<item>
  <bitmap android:src="@drawable/image"
          android:gravity="center" />
</item>複製程式碼

layer-list的強大之處在於,它的每一個item都可以是一個shape.例如,開始我們的控制元件有一個需求將控制元件顯示有一個1px邊框的矩形,如下圖

Android可繪製物件資源之shape和layer-list使用
這裡寫圖片描述

那麼我們一個可以通過一個shape就可以實現,如下

<?xml version="1.0" encoding="utf-8"?><!--    -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <solid android:color="@color/white" />
    <stroke
        android:width="1px"
        android:color="#9b9b9b" />
    <padding
        android:bottom="5dp"
        android:left="8dp"
        android:right="8dp"
        android:top="5dp" />
</shape>複製程式碼

那麼如果我們新的需求變更了,左右上邊框不展示了,即只展示下面的一條線,那麼怎麼實現呢,可能大家最常用的就是用一個1px高度的view加個背景色填充,但是如果我們想顯示左邊和邊的邊框呢?那麼需要再加View,佈局可能會很複雜。可能你也會說,shape可以指定android:shape="line"來繪製一條線,那麼我們來試試。

Android可繪製物件資源之shape和layer-list使用
這裡寫圖片描述

這就是實現的效果圖,發現,線是在中間,這肯定不是我們想要的效果,我們想要的效果是線在控制元件的最下方,其實此時shape已經不能滿足我們的需求了,但是layer-list可以實現,想有哪個邊框都可以。如下實現

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <shape>
            <solid android:color="#9b9b9b" />
        </shape>
    </item>
    <item android:bottom="1px">
        <shape>
            <solid android:color="@color/white" />
            <padding
                android:bottom="5dp"
                android:left="8dp"
                android:right="8dp"
                android:top="5dp" />
        </shape>
    </item>
</layer-list>複製程式碼

效果圖:

Android可繪製物件資源之shape和layer-list使用
這裡寫圖片描述

那麼如果我們想在控制元件左邊和下面顯示邊框線,那麼在上述lsyer-list中第二個item加一句 android:left="1px"就可以實現了。如下圖

Android可繪製物件資源之shape和layer-list使用
這裡寫圖片描述

是不是比用view填充方便呢,關於java程式碼實現可以直接去參考官方文件,詳情戳此連結。今天就介紹到這,有問題歡迎指出,Have a wonderful day.

相關文章