Android Drawable的那些事兒

weixin_33895657發表於2016-11-29

Drawable和View區別   ε-(´∀`; )

Drawable是一個抽象類,是對可繪製物件的抽象。
與View不同,Drawable沒有時間和互動的方法,而View直接面向使用者,可以為其新增事件。
Drawable有很多子類操作型別資源,如下

  • BitmapDrawable
  • LayerDrawable
  • StateListDrawable
  • ClipDrawable
  • LevelListDrawable
  • TransitionDrawable
  • InsertDrawable
  • ClipDrawable
  • ShapeDrawable
  • ……

╭( ′• o •′ )╭☞ Drawable原理

draw(Canvas canvas)在其中通過畫布進行繪製;
setBounds()指定繪製的邊界,通常傳入一個矩形的繪製物件對其進行繪製。


1.BitmapDrawable

BitmapDrawable是對bitmap的一種包裝,可以設定它所包裝的bitmap在BitmapDrawable區域內的繪製方式
包括:平鋪、拉伸或者保持原始大小等等

  • android:tileMode="mirror" 模式
    mirror:映象
    repeat:重複
    disable:平鋪
    clamp:圖片四周的畫素擴散到周圍區域

  • android:antialias="true" 抗鋸齒

  • android:dither="true" 抖動

  • android:filter="true" 過濾(圖片拉伸或壓縮建議開啟過濾)

<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/ic_avatar"
    android:tileMode="mirror"
    android:antialias="true"
    android:dither="true"
    android:filter="true">

</bitmap>

2.LayerDrawable

LayerDrawable管理一組drawable物件在LayerDrawable的繪製順序,列表最後一個drawable在最上層


layer-list
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:left="20dp"
        android:top="20dp">
        <bitmap
            android:gravity="center"
            android:src="@drawable/ic_avatar1"
    </item>
    
    <item
        android:left="20dp"
        android:top="20dp">
        <bitmap
            android:gravity="center"
            android:src="@drawable/ic_avatar2"
    </item>
</layer-list>

3.StateListDrawable

根據不同、狀態提供不同的背景。比如按鈕獲取失去焦點,點選等。

狀態 含義
android:state_pressed 按下的狀態,(按下但是還沒鬆開)
android:state_focused 當前View獲取了焦點
android:state_selected 使用者選擇了當前View
android:state_checked 使用者選中了View,一般用於CheckBox這種非黑即白的選項
android:state_enabled 當前View處於可用的狀態
android:state_hovered 游標是否懸停,通常與focused state相同,它是4.0的新特性
android:state_checkable 元件是否能被check。如:RadioButton是可以被check的。
android:state_activated 是否被啟用
android:state_window_focused 應用程式是否在前臺,當有通知欄被拉下來或者一個對話方塊彈出的時候應用程式就不在前臺了
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
   <item android:state_focused="true" android:drawable="@drawable/ic_down"></item>
   <item android:state_pressed="true" android:drawable="@drawable/ic_select"></item>
   <item android:state_selected="true" android:drawable="@drawable/ic_select"></item>
   <item android:drawable="@drawable/ic"></item>
</selector>

( ´◔‸◔`)    為毛一定要在最後加一個預設的狀態?
每個item對應一個具體drawable,系統從上到下進行查詢,直到匹配;所以,如果沒找到就選擇預設的,啊哈哈,留一手。

粉嫩嫩的下邊框

EditText下邊框

<?xml version="1.0" encoding="utf-8"?>
<selector
  xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" >
        <shape android:shape="rectangle">
            <corners android:radius="5dp" />
            <solid android:color="@color/deeppink" />
         </shape>
    </item>
    <item >
        <shape android:shape="rectangle">
            <corners android:radius="5dp" />
            <solid android:color="@color/pink" />
         </shape>
    </item>
</selector>

4.LevelListDrawable

管理一組drawable資源,通過呼叫setLevel()方法載入listvel-list或程式碼中定義的某個drawable資源,範圍0-10000,夠用不?

<?xml version="1.0" encoding="utf-8"?>
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:drawable="@drawable/ic_on"
        android:maxLevel="10"
        android:minLevel="6">
    </item>
    <item
        android:drawable="@drawable/ic_off"
        android:maxLevel="20"
        android:minLevel="12">
    </item>
</level-list>

在程式碼中設定imageView.setImageLevel(8);

5.TransitionDrawable

為LayerDrawable子類,只管理兩層,提供透明度變化,可以控制從一層過度到另一層的動畫效果

<?xml version="1.0" encoding="utf-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/ic_on"></item>
    <item android:drawable="@drawable/ic_off"></item>
</transition>

在程式碼中


TransitionDrawable drawable = (TransitionDrawable)v.getDrawable();
drawable.startTransition(3000);

// ↓ 變身

TransitionDrawable drawable = (TransitionDrawable)v.getDrawable();
drawable.reverseTransition(3000); // /漸變時間3s

6.InsertDrawable

嵌入到另一個drawable,可以設定inset內邊距

inset
<?xml version="1.0" encoding="utf-8"?>
<inset xmlns:android="http://schemas.android.com/apk/res/android"
       android:drawable="@drawable/ic_avatar"
       android:inset="50dp">
</inset>

7.ClipDrawable

對drawable進行剪下,通過setLevel進行剪下,level從0-10000

裁剪方式android:clipOrientation="horizontal"

<?xml version="1.0" encoding="utf-8"?>
<clip xmlns:android="http://schemas.android.com/apk/res/android"
      android:clipOrientation="horizontal"
      android:drawable="@drawable/ic_avatar"
      android:gravity="left">
</clip>

橫向顯示圖片的一半(5000)

ClipDrawable drawable = (ClipDrawable)v.getDrawable();
drawable.setLevel(5000);

8.ShapeDrawable

android:shape="oval" 圖片形狀 rectangle(預設)、oval(橢圓)、line、ring
android:angle 漸變的角度 預設為0,值為45的倍數,0表示從左往右,90表示從下到上
corners 圓角角度 適用於矩形
solid 純色填充
gradient 漸變效果 與solid相排斥
stroke 描邊 android:width 寬度、android:color 顏色 、android:dashWidth 虛線線段寬度、android:dashGap 註冊虛線之間的間距
size shape大小 size指定寬高後,ShapeDrawable就有固定寬/高
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="oval">
    <corners
        android:bottomLeftRadius="10dp"
        android:bottomRightRadius="10dp"
        android:radius="5dp"
        android:topLeftRadius="10dp"
        android:topRightRadius="10dp"/>
    <gradient
        android:angle="0"
        android:centerColor="#cccccc"
        android:centerX="100"
        android:centerY="20"
        android:endColor="#abcdef"
        android:gradientRadius="100dp"
        android:startColor="#000000"
        android:type="linear"
        android:useLevel="false"/>
    <solid android:color="#cccccc"/>
    <stroke
        android:width="1dp"
        android:color="#cccccc"
        android:dashGap="2dp"
        android:dashWidth="50dp"/>
</shape>

eg:文字加入邊框

<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
       android:shape="rectangle">
    <solid android:color="#ffffff"/>
    <corners android:radius="5dip"/>
</shape>

相關文章