Android – Drawable 詳解

weixin_34321977發表於2017-12-19

很早看過這篇文章,並做了筆記,後來看到群裡的小夥伴有問相關Drawable的問題,就把這篇翻譯過來的文章給放出來了。大家一起學習,一起進步。想看原文的小夥伴可以點選下面的連結。
原文地址

前言

Drawable是可以繪製到螢幕上的圖形。 Drawable用於定義形狀,顏色,邊界,漸變等,然後將其應用於Activity中的View。
這通常用於自定義顯示在特定View。 Drawable傾向於在XML中定義,然後可以通過XML或Java程式碼應用於View。
有關Android的每個版本的預設Drawable列表,請參考androiddrawables網站。

用法

在不同情況下有很多可繪製的型別,設定按鈕的狀態行為,建立可伸縮的按鈕背景和建立複合可繪製圖層。
至少有17種可繪製型別,但有五個最重要的:
Shape Drawables - 定義具有例如:stroke(描邊),fill(填充)和padding(內邊距)等屬性的形狀
StateList Drawables - 定義用於不同狀態的Drawable
LayerList Drawables - 定義分組在一起成為複合結果的Drawable
NinePatch Drawables - 具有可伸縮區域的PNG圖片,以允許適當調整大小
Vector Drawables - 定義複雜的基於XML的向量影象

下面讓我們一一介紹它們的使用方法

Shape

Shape Drawable是一個XML檔案,它定義了幾何形狀,包括顏色和漸變。這用於建立一個複雜的形狀,然後可以作為佈局或檢視的背景附加在螢幕上。例如,可以使用可繪製的形狀來更改按鈕背景的形狀,邊框和漸變。

一個形狀只是一個屬性的集合,被合併來描述一個背景。形狀可以用屬性來描述,如圓角,背景漸變,間距填充,背景顏色固定,描邊等。

純色 Shapes

下面是一個繪製帶有邊框的圓角矩形的示例:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >
    <corners android:radius="4dp" />
    <stroke android:width="4dp" android:color="#C1E1A6" /> 
    <solid android:color="#118C4E"/> 
    <padding android:left="20dp" android:top="20dp" 
             android:right="20dp" android:bottom="20dp" /> 
</shape>

然後在TextView的background屬性裡應用:

<TextView
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:background="@drawable/solid_color_shape"
   android:textColor="#ffffff"
   android:text="@string/hello_world" />

結果看起來像下面這樣:


2726727-002f34624d419618.png

注意,drawables可以應用於任何View及ViewGroup,通常是通過background屬性來設定Drawable資源的。

漸變色的 Shapes

形狀也支援 gradients backgrounds(漸變背景)支援的屬性,如startColor,centerColor,endColor,角度。可以使用型別屬性選擇不同的漸變,如徑向,線性或掃描。

下面是一個簡單的線性漸變形狀的例子:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >
    <corners android:radius="4dp" />
    <stroke android:width="1dp" android:color="#0078a5" /> 
    <gradient
        android:startColor="#0078a5" android:endColor="#00adee" 
        android:angle="90"/>
    <padding android:left="8dp" android:top="2dp" 
             android:right="8dp" android:bottom="2dp" /> 
</shape>

結果看起來像下面這樣:


2726727-92270660cea3a0ff.png

你還可以使用以下設定徑向型別漸變:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle" >
    <corners android:radius="4dp" />
    <stroke android:width="4dp" android:color="#CCFFFF" /> 
    <gradient
        android:startColor="#0078a5" 
        android:endColor="#CCFFFF" 
        android:gradientRadius="250"
        android:type="radial"
        />
    <padding android:left="30dp" android:top="30dp" 
             android:right="30dp" android:bottom="30dp" /> 
</shape>

應用於TextView時,看起來像下面這樣:


2726727-18b08020b27b905f.png

使用純色形狀和漸變,我們可以自定義按鈕,佈局和其他檢視的外觀,而不需要使用任何圖片。請注意,可以使用PathShape和ArcShape在執行時建立自定義形狀。

Drawable List 狀態集合

StateListDrawable是一個在XML中定義的可繪製物件,根據物件的狀態,使用多個不同的影象來表示相同的圖形。例如,Button控制元件可以以幾種不同的狀態之一存在(按下,有焦點或不可點選),並且使用Drawable的狀態列表,可以為每個狀態提供不同的背景影象。例如:android:state_pressed,android:state_focused,android:state_enabled,android:state_selected等等。下圖顯示了可以表示的所有主要狀態:

2726727-5bc3fd587614ab00.png

例如,按鈕背景的狀態列表XML可能類似於以下檔案中的內容:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:state_pressed="true"
        android:state_enabled="true"
        android:drawable="@drawable/button_pressed" />
    <item
        android:state_focused="true"
        android:state_enabled="true"
        android:drawable="@drawable/button_focused" />
    <item
        android:state_enabled="true"
        android:drawable="@drawable/button_enabled" />
</selector>

現在,當檢視(即按鈕)被按下或聚焦時,用於檢視的drawable將相應地改變。請注意,任何檢視都有一個狀態選擇器,但最常見的用途是按鈕和列表檢視專案。也有顏色狀態選擇器,允許根據檢視狀態來選擇顏色。

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:color="#ffff0000"/> 
    <item android:state_focused="true" android:color="#ff0000ff"/> 
    <item android:color="#ff000000"/> 
</selector>

並應用於佈局檔案中按鈕的textColor屬性等顏色值的任何欄位:

<Button
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/button_text"
    android:textColor="@color/button_text" />

使用狀態列表允許我們輕鬆定義響應按下,是否選中,是否可用或其他相關狀態的動態檢視。

建立 Layer List

一個LayerDrawable是一個drawable物件,管理其它的drawable陣列。列表中的每個drawable都按照列表的順序繪製 - 列表中的最後一個drawable繪製在頂部。每個drawable由單個<layer-list>元素內的<item>元素表示。

LayerList可以用來繪製多個其它的drawable(形狀,影象等),並將它們放置在相互之間的關係中。預設情況下,圖層被放置在另一個的頂部,最後一個圖層被繪製在頂部。然後可以使用left, right, top, and bottom屬性來移動圖層的座標。

2726727-3104315f69bee65e.png

圖層樣式的常見用例包括:
View邊框陰影
View單邊新增邊框
View分層背景
View卡片背景
繪製三角形

舉一個簡單的例子,下面的圖層列表繪製了幾個相互關聯的形狀:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item>
      <shape 
        android:shape="rectangle">
            <size android:width="280dp" android:height="140dp"/>
            <stroke android:width="1dp" android:color="#585858" />
            <solid android:color="#FF9009" />
            <padding android:bottom="1dp"/>
        </shape>
   </item>
   <item android:left="10dp" android:top="20dp" android:bottom="20dp" android:right="150dp">
      <shape 
        android:shape="oval">
            <stroke android:width="1dp" android:color="#ffffff" />
            <solid android:color="#118C4E" />
            <padding android:bottom="1dp"/>
        </shape>
   </item>
   <item android:left="150dp" android:top="20dp" android:bottom="20dp" android:right="10dp">
      <shape 
        android:shape="rectangle">
            <stroke android:width="1dp" android:color="#ffffff" />
            <solid android:color="#C1E1A6" />
            <padding android:bottom="1dp"/>
        </shape>
   </item>
</layer-list>

結果看起來像下面這樣:

2726727-1665f1a14bfb2e0b.png

請記住,LayerList中的item也可以是影象或任何其他型別的drawable。你可以使用它來建立更復雜的drawable,並將多個drawable疊加在一起。在官方文件中檢視更多示例。

可伸縮的 Nine-Patch Image

NinePatch是一個PNG影象,你可以在該影象中定義當View的內容超出正常影象邊界時定義拉伸的可伸展區域。通常將此型別的影象作為View的背景,將其寬度設定為wrap_content。最常見的用法是一個Button,它必須根據裡面顯示的文字來拉伸。

2726727-236f3eed08308a5e.png

NinePatch是具有.9.png副檔名的影象,表示這是一個可伸縮的PNG影象。該檔案與正常的PNG檔案沒有什麼不同,除了您將新增細黑線以指示影象的垂直和水平“可拉伸”和“填充”區域。Android不會顯示這些guide lines(指導線),這些guide lines(指導線)用於確定如何呈現影象。
下面嵌入了一個9-patch image的例子(左邊是9patch圖形,右邊是在應用程式中使用的一個例子):
2726727-84db2a18cb54f2a1.png

NinePatch被定義並儲存在drawable資料夾中,並將背景設定為與任何影象相同:

<Button android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Submit"
        android:background="@drawable/button_background"/>

Android Studio可以直接編輯9-patch檔案。你的PNG檔案只需儲存在drawable資料夾中以.9.png為副檔名,即可顯示9-patch編輯器,而不是普通的影象編輯器。你可以使用滑鼠來選擇要拉伸的區域(使用Shift鍵並單擊並拖動滑鼠擦除區域),右側的預覽窗格將顯示如何根據內部文字渲染影象。


2726727-82ea826c644ff9b5.png

需要為可拉伸區域定義左邊和上邊的線。為了避免在上面的例子中拉伸這個氣泡的箭頭,我們定義了這個區域之外的區域。右側和底部的行定義了可以填充文字的位置。如果沒有底線,您的文字將不會填滿拉伸區域的整個寬度,並且可能無法正確居中。

有關更多資訊,可以參考這個簡單的操作指南。你也可以參考官方的文件

Vector Drawables(向量圖)

這些XML是可繪製的,可以定義複雜的基於向量的影象,可以自動縮放以支援所有的密度。這意味著使用基於向量的影象,在點陣圖影象的情況下,你只需要一個drawable file,而不是每個螢幕密度的drawable file。

首先,請參考設定指南以啟用對pre-Lollipop devices(棒棒糖前裝置)的向量繪圖支援。

建立 Vector Drawables

要建立一個向量影象,您需要定義位於這裡的pathData語法。本示例使用以下內容定義XML元素中的形狀細節:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:height="256dp"
    android:width="256dp"
    android:viewportWidth="32"
    android:viewportHeight="32">
  <!-- draw a path -->
  <path android:fillColor="#c9c10606"
      android:pathData="M20.5,9.5
                        c-1.955,0,-3.83,1.268,-4.5,3
                        c-0.67,-1.732,-2.547,-3,-4.5,-3
                        C8.957,9.5,7,11.432,7,14
                        c0,3.53,3.793,6.257,9,11.5
                        c5.207,-5.242,9,-7.97,9,-11.5
                        C25,11.432,23.043,9.5,20.5,9.5z" />
</vector>

使用 Vector Drawables

然後,我們可以使用app:srcCompat屬性來載入:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <ImageView  
      android:layout_width="wrap_content"  
      android:layout_height="wrap_content"  
      app:srcCompat="@drawable/ic_heart" />  
</RelativeLayout>

注意:請務必使用app:srcCompat來支援較舊的Android裝置。如果你使用android:src作為vector drawable,你的應用可能會在較新的裝置中正確呈現,但可能會在棒棒糖前裝置中崩潰。
最終顯示如下圖所示:


2726727-abfe3978bcd8dcf7.png

你也可以在執行時使用程式碼來設定vector drawable:

ImageView iv = (ImageView) findViewById(...);
iv.setImageResource(R.drawable.ic_heart);

查詢 Vector Drawables

現在可以在Android Studio中直接找到vector drawable,也可以在許多Android資源網站上找到。假設您已更新到Android Studio v2.2,您可以在File => New => Vector Asset嚮導中檢查vector drawable:

2726727-c62edc2c0c7b16f0.png

您可以在material design icons website上找到其他圖示,其中也包含社群貢獻的圖示。
2726727-4fb9c8dddbea6568.png

轉換為Vector Drawable

另外,有幾種方法可以直接從SVG圖形建立vector drawable:
Vector Asset Studio - 是Android Studio中包含的一個實用工具(如上所示),用於將SVG asstes轉換為vector drawable
SVG2Android Online Utility - 直接在瀏覽器中將SVG轉換為vector drawable
Command-line SVG Converter - 可以將SVG批量轉換為vector drawable
Vectorizer - 將PNG影象轉換為SVG以轉換為vector drawable

自定義 Button

建立自定義按鈕需要至少組合一個drawable的狀態列表和一個drawable的形狀。首先,我們來建立一個drawable的形狀,res / drawable / nice_button_enabled.xml中的“預設”按鈕背景:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
    <gradient
        android:startColor="#0078a5"
        android:endColor="#00adee"
        android:angle="90"/>
    <padding android:left="15dp"
        android:top="1dp"
        android:right="15dp"
        android:bottom="1dp" />
    <stroke
        android:width="1dp"
        android:color="#0076a3" />
    <corners android:radius="8dp" />
</shape>

我們還要建立一個style(檢視屬性集),其中包含在res / values / styles.xml中設定背景:

<style name="NiceButton" parent="@android:style/Widget.Button">
    <item name="android:gravity">center_vertical|center_horizontal</item>
    <item name="android:textColor">#FFFFFF</item>
    <item name="android:background">@drawable/nice_button_enabled</item>
    <item name="android:textSize">16sp</item>
    <item name="android:textStyle">bold</item>
    <item name="android:focusable">true</item>
    <item name="android:clickable">true</item>
</style>

這代表預設狀態下按鈕的形狀和背景以及其他屬性。我們可以通過設定按鈕的style來應用這個:

<Button
    android:id="@+id/btnGo"
    style="@style/NiceButton"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
/>

結果會像下面這樣:


2726727-f9d2302fa09adb19.png

現在Button很好地顯示,但沒有任何“按下”或“聚焦”的狀態。要做到這一點,我們需要建立一個狀態列表drawable來表示res / drawable / states_nice_button.xml中每個狀態的drawable。

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:state_pressed="true"
        android:state_enabled="true"
        android:drawable="@drawable/nice_button_pressed" />
    <item
        android:state_focused="true"
        android:state_enabled="true"
        android:drawable="@drawable/nice_button_focused" />
    <item
        android:state_enabled="true"
        android:drawable="@drawable/nice_button_enabled" />
</selector>

這描述了在所有三個主要狀態(預設,按下和聚焦)中Button的外觀。現在我們需要建立兩個Shape drawable狀態。一個用於res / drawable / nice_button_pressed.xml,另一個用於res / drawable / nice_button_focused.xml:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
    <gradient
        android:startColor="#00adee"
        android:endColor="#0078a5"
        android:angle="90"/>
    <padding android:left="15dp"
        android:top="1dp"
        android:right="15dp"
        android:bottom="1dp" />
    <stroke
        android:width="1dp"
        android:color="#0076a3" />
    <corners android:radius="8dp" />
</shape>

按壓和聚焦的狀態將顯示相同,但​​這些也可能是不同的視覺狀態。現在,我們需要改變style來使用res / drawable / states_nice_button.xml:

<style name="NiceButton" parent="@android:style/Widget.Button">
    <item name="android:gravity">center_vertical|center_horizontal</item>
    <item name="android:textColor">#FFFFFF</item>
    <item name="android:background">@drawable/states_nice_button</item>
    <item name="android:textSize">16sp</item>
    <item name="android:textStyle">bold</item>
    <item name="android:focusable">true</item>
    <item name="android:clickable">true</item>
</style>

現在我們有一個Button,它有一個很好的形狀drawable背景,當按下時不需要單個影象資源就可以改變視覺狀態!

自定義ListView

另一個常見需求是自定義ListView中專案的外觀。首先讓我們建立基本的ListView並在其中填充String專案。首先,res / layout / item_simple.xml中專案的佈局XML:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/text1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center_vertical"
    android:padding="5dp"
    android:text="Large Text"
    android:textAppearance="?android:attr/textAppearanceLarge" />

接下來,讓我們在一個activity中設定基本的ListView xml:

<ListView
       android:id="@+id/lvTest"
       android:layout_width="match_parent"
       android:layout_height="wrap_content">
</ListView>

然後填充ListView:

ArrayList<String> items = new ArrayList<String>();
for (int i = 1; i < 8; i++) {
    items.add("Item " + i);
}
ArrayAdapter<String> aItems = new ArrayAdapter<String>(this, R.layout.item_simple, items);
lvTest = (ListView) findViewById(R.id.lvTest);
lvTest.setAdapter(aItems);

結果看起來像下面這樣:


2726727-80fdb9fba45d7456.png

現在,讓我們將自己的樣式新增到ListView。讓我們新增一個預設的漸變和一個按下的漸變,改變專案之間的分隔線顏色,並在ListView周圍新增一個邊框。首先,我們在res / drawable / gradient_bg.xml中為預設狀態新增形狀漸變背景:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
  <gradient
      android:startColor="#f1f1f2"
      android:centerColor="#e7e7e8"
      android:endColor="#cfcfcf"
      android:angle="270" />
</shape>

然後在res / drawable / gradient_pressed_bg.xml中新增按下漸變背景:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
  <gradient
      android:startColor="#C1E1A6"
      android:endColor="#118C4E"
      android:angle="270" />
</shape>

然後讓我們建立一個狀態列表來描述在各種列表狀態中使用的drawable:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:state_selected="false"
        android:state_pressed="false"
        android:drawable="@drawable/gradient_bg" />

    <item android:state_pressed="true"
          android:drawable="@drawable/gradient_pressed_bg" />
 
    <item android:state_selected="true"
          android:state_pressed="false"
          android:drawable="@drawable/gradient_pressed_bg" />
</selector>

接下來,我們通過設定“stroke”屬性,在res / drawable / list_border.xml中使用一個Shape drawable設定ListView的邊框:

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle" >
    <stroke android:width="1dp" android:color="#b5b5b5" />
    <solid android:color="#00000000" />
</shape>

現在讓我們將這些XML drawable中的每一個應用於各種元素。首先,我們將背景新增到列表項本身並調整res / layout / item_simple.xml:

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    ...
    android:background="@drawable/states_selector_list" />

請注意,背景屬性已設定為狀態列表,以便為專案應用預設背景。接下來,讓我們將邊框和選擇器狀態新增到活動佈局檔案中的現有ListView:

<ListView
   ...
   android:padding="1dp"
   android:divider="#b5b5b5"
   android:dividerHeight="1dp"
   android:background="@drawable/list_border"
   android:listSelector="@drawable/states_selector_list" >
</ListView>

在這裡我們定製了divider color和dividerHeight以及背景來應用border和listSelector來管理一個item被按下時的狀態。有了這一切,我們的自定義ListView現在看起來像:


2726727-656cab5a82a6439f.png

我們現在已經成功地定製了我們的ListView的外觀,並且它使用了一系列drawable。

執行時Drawables

我們可以通過訪問具有可繪製應用的檢視的背景,在我們的Java程式碼的執行時訪問drawable。例如,給res / drawables / message_bubble.xml這個層列表:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
    <item android:id="@+id/outerRectangle">
        <shape android:shape="rectangle" >
            <solid android:color="#FF00FF" />
        </shape>
    </item>
    <item android:left="10dp">
        <shape android:shape="rectangle" >
            <solid android:color="#ffccd2" />
        </shape>
    </item>
</layer-list>

然後我們可以從我們的activity中通過指定的id訪問outerRectangle:

// Get drawable layer list from the background
LayerDrawable bubble = (LayerDrawable) tvFoo.getBackground();
// Access 
GradientDrawable outerRect = (GradientDrawable) 
  bubble.findDrawableByLayerId(R.id.outerRectangle);
// Change the solid color of the drawable 
outerRect.setColor(Color.parseColor("#2f8f22"));

請注意,即使形狀是純色,此形狀也是作為GradientDrawable訪問的。

執行時Vector Drawables

如果你在執行時使用 vector drawables或animated vector drawables,請確保使用新的AppCompatResource類而不是普通的getDrawable()呼叫,特別是如果您在繪圖中引用自定義主題屬性(即?attr / colorAccent):

// Use AppCompatResource so that it will accurately use theme attributes
Drawable drawable = AppCompatResources.getDrawable(R.drawable.ic_test_24dp);

// Use this drawable
ImageView imageView = (ImageView) findViewById(R.id.tst);
imageView.setBackground(drawable);

應用著色器

從Android 5.0及更高版本開始,現在可以將tint color應用於drawable。其優點是根據當前主題使用的影象風格。例如,在Twitter最近的Android UI更新中,大多數影象以黑色的形式儲存為vector drawables:

2726727-11c5fd5404d79a78.png

這裡是對應的vector drawable:

<?xml version="1.0" encoding="utf-8"?>
<vector android:height="24.0dip" android:width="24.0dip" android:viewportWidth="24.0" android:viewportHeight="24.0"
  xmlns:android="http://schemas.android.com/apk/res/android">
    <path android:fillColor="#ff000000" android:pathData="M22.46,7.57L12.357,2.115c-0.223,-0.12 -0.49,-0.12 -0.713,0L1.543,7.57c-0.364,0.197 -0.5,0.652 -0.303,1.017 0.135,0.25 0.394,0.393 0.66,0.393 0.12,0 0.243,-0.03 0.356,-0.09l0.815,-0.44L4.7,19.963c0.214,1.215 1.308,2.062 2.658,2.062h9.282c1.352,0 2.445,-0.848 2.663,-2.087l1.626,-11.49 0.818,0.442c0.364,0.193 0.82,0.06 1.017,-0.304 0.196,-0.363 0.06,-0.818 -0.304,-1.016zM17.822,19.703c-0.107,0.606 -0.703,0.822 -1.18,0.822L7.36,20.525c-0.48,0 -1.075,-0.216 -1.178,-0.798L4.48,7.69 12,3.628l7.522,4.06 -1.7,12.015z" />
    <path android:fillColor="#ff000000" android:pathData="M8.22,12.184c0,2.084 1.695,3.78 3.78,3.78s3.78,-1.696 3.78,-3.78 -1.695,-3.78 -3.78,-3.78 -3.78,1.696 -3.78,3.78zM14.28,12.184c0,1.258 -1.022,2.28 -2.28,2.28s-2.28,-1.022 -2.28,-2.28 1.022,-2.28 2.28,-2.28 2.28,1.022 2.28,2.28z" />
</vector>

首先,我們將顏色新增到我們的colors.xml檔案中:

<color name="twitter_blue">#ff1da1f2</color>
<color name="medium_gray">#ffaab8c2</color>

將此vector drawable更改為藍色的最簡單方法是將android:tint屬性應用於<vector>標記:

<vector 
   android:tint="@color/twitter_blue">

</vector>

我們也可以動態改變這個:

ColorStateList colors;
if (Build.VERSION.SDK_INT >= 23) {
  colors = getResources().getColorStateList(R.color.twitter_blue, getTheme());
}
else {
  colors = getResources().getColorStateList(R.color.twitter_blue);
}

// Use for pre-Lollipop devices
Drawable drawable = AppCompatResources.getDrawable(R.drawable.ic_test_24dp);
// Wrap the drawable so that future tinting calls work on pre-v21 devices. 
Drawable icon = DrawableCompat.wrap(drawable);
DrawableCompat.setTintList(icon, colors);
}

注意,使用的著色顏色也可以使用可繪製的狀態列表。例如,如果我們希望色彩根據圖示是否被選中而改變顏色,我們可以建立一個res / color / tab_selector.xml:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
   <item android:color="@color/twitter_blue" android:state_selected="true"></item>
   <item android:color="@color/medium_gray" />
</selector>

額外的drawable型別

LevelList - 一個Drawable,管理一些替代Drawables,每個分配一個最大數值。
TransitionDrawable - 可繪製的物件,可以在兩個drawable資源之間交叉淡入淡出。用於兩個drawable之間的動畫。
InsetDrawable - 在XML中定義的drawable表示將另一個drawable物件按指定的距離進行插入。當View需要比View的實際邊界更小的背景時,這是非常有用的。
ClipDrawable - 在XML中定義一個drawable,根據這個Drawable的當前級別剪下另一個drawable。最常用來實現諸如進度條之類的東西。
ScaleDrawable - XML中定義的drawable根據當前級別更改另一個drawable的大小。

工具

參考

相關文章