Drawable是一個抽象類,是可繪制物件的抽象。與View不同,Drawable沒有事件和互動的方法。一般情況下,Drawable附着在一個View上。不同的Drawable子類用于操作不同的資源類型,如BitmapDrawable用于操作位圖,ColorDrawable用于操作顔色,ClipDrawable用于操作剪切闆。
Drawable的原理:
Drawable主要調用本身的兩個方法進行繪制:
- draw(Canvas canvas):與View類似,該方法用于在canvas畫布上進行繪制,而畫布是由drawable上所附着的View對象決定的;
- setBounds()方法用于指定繪制的邊界,通常傳入一個Rect矩形對象。
如需了解Drawable的官方介紹,您可以點選這個連結:《Android官方文檔之App Resources(下)》。
BitmapDrawable
BitmapDrawable是對Bitmap的一種包裝,可以設定它包裝的Bitmap在BitmapDrawable區域内的繪制方式,如平鋪填充、拉伸填充、或保持圖檔原始大小 等。
用法:
在res/drawable中建立一個bitmap.xml檔案,并指定它的根标簽為
<bitmap>
,如下所示:
<!-- bitmap.xml -->
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:antialias="true"
android:src="@drawable/ic_launcher"
android:tileMode="mirror"
android:dither="true">
</bitmap>
其中,
- android:antialias為抗鋸齒屬性,設為true表示使得圖檔邊緣顯式更為平滑,但影響效率。
- android:tileMode屬性為平鋪模式,預設為disable,即不平鋪,還有三個屬性:clamp ,複制邊緣色彩;repeat ,X、Y 軸進行重複圖檔顯示,也就是平鋪; mirror,在水準和垂直方向上使用交替鏡像的方式重複圖檔的繪制。
- android:dither:抖動,Dither(圖像的抖動處理,當每個顔色值以低于8位表示時,對應圖像做抖動處理可以實作在可顯示顔色總數比較低(比如256色)時還保持較好的顯示效果。預設為true。
将該bitmap.xml設定為activity_main.xml的背景時的預覽效果:
1、将tilemode屬性設為mirror時:
2、将tilemode屬性設為repeat時:
3、将tilemode屬性設為clamp時:
4、将tilemode屬性設為disabled時(預設):
dither屬性對比圖:(來自維基百科)
LayerDrawable
可以管理一組Drawable對象,并按照清單的順序進行繪制,清單的最後一個Drawable繪制在最上層。
在res/drawable中建立一個layer.xml檔案,并指定其根标簽為
<layer-list>
,如下所示:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="@drawable/ic_launcher"
android:gravity="center" />
<item
android:drawable="@drawable/ic_launcher"
android:left="30dp"
android:top="30dp"
android:gravity="center" />
</layer-list>
其中第二個item将覆寫在第一個item之上,屬性android:left與android:top分别表示基于第一個item的位置所向右偏移與向下偏移的距離。效果如下所示:
StateListDrawable
可以根據不同的狀态提供不同的背景,比如一個按鈕有多種狀态:擷取焦點、失去焦點、點選 等。
res/drawable中建立state_list.xml,并指定根标簽為
<state-list>
,代碼如下:
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/unclick" android:state_focused="true" />
<item android:drawable="@drawable/clicked" android:state_pressed="true" />
<item android:drawable="@drawable/unclick" android:state_selected="true" />
<item android:drawable="@drawable/unclick" />
</selector>
并在Button中應用,效果略。
LevelListDrawable
用于管理一組drawable資源,LevelListDrawable裡的每一個drawable資源與一個最大數值結合起來,作為LevelListDrawable資源的一項;調用Drawable的setLevel()方法可以加載level-list或代碼中的某個drawable資源。
在res/drawable目錄下建立檔案level_list.xml檔案,并指定根标簽為
<level-list>
,如下:
<!-- level_list.xml -->
<level-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="@drawable/unclick"
android:maxLevel="10"
android:minLevel="6" />
<item
android:drawable="@drawable/clicked"
android:maxLevel="20"
android:minLevel="12" />
</level-list>
其中屬性 android:maxLevel與 android:minLevel分别最大級别和最小級别,在該級别之間時,将顯示這個item中的圖檔。
将該level_list.xml檔案設定給ImageView的background屬性,并在Activity中調用
方法,可以設定級别,在item中切換。
TransitionDrawable
TransitionDrawable是LayerDrawable的子類,不過它隻負責管理兩層drawable,并提供了一個透明度變化的動畫,可以控制從一層drawable到另一層drawable的動畫效果。
在res/drawable中建立transition.xml檔案,并指定根标簽為
<transition>
,代碼如下:
<!-- transition.xml -->
<transition xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/unclick" />
<item android:drawable="@drawable/clicked" />
</transition>
在Java代碼中,在點選事件中添加代碼:
TransitionDrawable drawable = (TransitionDrawable) mImageView.getBackground();
drawable.startTransition();
drawable将在2秒内由第一個item的圖檔漸變到第二個item的圖檔。
InsetDrawable
表示将一個drawable嵌入到另一個drawable内部,并且在内部留一些間距,這一點很像drawable的padding屬性。
在res/drawable中建立inset.xml檔案,指定根标簽為
<inset>
:
<!-- inset.xml -->
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="#FF0000"
android:insetBottom="50dp"
android:insetLeft="50dp"
android:insetRight="50dp"
android:insetTop="50dp">
</inset>
屬性android:insetBottom表示該drawable與底部的距離,類似于paddingBottom屬性。在ImageView中指定其背景為inset.xml,效果如下:
ClipDrawable
ClipDrawable是對Drawable進行剪切操作,并控制剪切區域。
在Android中,進度條就是通過ClipDrawable實作的,它根據level這個屬性值,确定裁剪的區域大小
ClipDrawable通過setLevel(int level)方法來設定剪切區域。level取值從0~10000,0表示完全不顯示,10000表示完全顯示。
在res/drawable在建立clip.xml,并指定根标簽為
<clip>
,如下所示:
<clip xmlns:android="http://schemas.android.com/apk/res/android"
android:clipOrientation="horizontal"
android:drawable="@drawable/ic_launcher">
</clip>
在Activity中設定剪裁尺寸:
mImageView = (ImageView) findViewById(R.id.mImageView);
ClipDrawable drawable = (ClipDrawable) mImageView.getDrawable();
drawable.setLevel();
這表示隻保留了圖檔的左半邊區域。