天天看點

Android中的各種DrawableBitmapDrawableLayerDrawableStateListDrawableLevelListDrawableTransitionDrawableInsetDrawableClipDrawable

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時:

Android中的各種DrawableBitmapDrawableLayerDrawableStateListDrawableLevelListDrawableTransitionDrawableInsetDrawableClipDrawable

2、将tilemode屬性設為repeat時:

Android中的各種DrawableBitmapDrawableLayerDrawableStateListDrawableLevelListDrawableTransitionDrawableInsetDrawableClipDrawable

3、将tilemode屬性設為clamp時:

Android中的各種DrawableBitmapDrawableLayerDrawableStateListDrawableLevelListDrawableTransitionDrawableInsetDrawableClipDrawable

4、将tilemode屬性設為disabled時(預設):

Android中的各種DrawableBitmapDrawableLayerDrawableStateListDrawableLevelListDrawableTransitionDrawableInsetDrawableClipDrawable

dither屬性對比圖:(來自維基百科)

Android中的各種DrawableBitmapDrawableLayerDrawableStateListDrawableLevelListDrawableTransitionDrawableInsetDrawableClipDrawable

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的位置所向右偏移與向下偏移的距離。效果如下所示:

Android中的各種DrawableBitmapDrawableLayerDrawableStateListDrawableLevelListDrawableTransitionDrawableInsetDrawableClipDrawable

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,效果如下:

Android中的各種DrawableBitmapDrawableLayerDrawableStateListDrawableLevelListDrawableTransitionDrawableInsetDrawableClipDrawable

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();
           

這表示隻保留了圖檔的左半邊區域。