1. 程式人生 > >Android中Drawable分類彙總(上)

Android中Drawable分類彙總(上)

Android把可繪製的物件抽象為Drawable,不同的圖形影象資源就代表著不同的drawable型別。Android FrameWork提供了一些具體的Drawable實現,通常在程式碼中都不會直接接觸Drawable的實現類。         在實際的開發過程中,會把使用到的資源都放置在res/drawable目錄,剩下的工作交給Android SDK 就行了,當需要使用圖片資源的時候,可以使用@drawable標誌在xml中引用drawable資源就行,也可以在程式碼中使用id引用這些drawable資源。         在使用drawable資源的時,有一點需要注意,drawable預設是記憶體共享的,也就說在不同的地方使用了同一個drawable,它們都指向相同的資源,而且具有相同的狀態,如果在一個地方修改了這個drawable,所有使用它的地方都會改變。         Android內建瞭如下幾種Drawable型別:ColorDrawable、GradientDrawable、BitmapDrawable、 NinePatchDrawable、InsetDrawable、ClipDrawable、ScaleDrawable、RotateDrawable、AnimationDrawable、LayerDrawable、LevelListDrawable、StateListDrawable、TransitionDrawable。         除了這些預置的drawable實現類以外,也可以自定義drawable的實現型別,大部分情況都不需要自定義drawable型別,使用系統提供的這些drawable實現型別已經覆蓋了很多情況。在實際的程式設計過程中也很少會接觸這些具體drawable實現型別,因為編寫android應用程式使用xml可以很容易的建立drawable,只有在程式中需要修改drawable的屬性時,才需要使用具體的drawable型別提供的方法來處理。下面就來逐個認識這些Drawable型別。 一、ColorDrawable         ColorDrawable 是最簡單的Drawable,它實際上是代表了單色可繪製區域,它包裝了一種固定的顏色,當ColorDrawable被繪製到畫布的時候會使用顏色填充Paint,在畫布上繪製一塊單色的區域。         在xml檔案中使用color作為根節點來建立ColorDrawable,它只有一個android:color屬性,通過它來決定ColorDrawable的顏色,Android並沒有提供修改這個顏色值的Api,所以這個顏色一旦設定之後,就不能直接修改了。         下面的xml檔案定義了一個顏色為紅色的ColorDrawable:

[程式碼]xml程式碼:

1 <?xml version="1.0" encoding="utf-8"?>
2 <color xmlns:android="http://schemas.android.com/apk/res/android"
3 android:color="#FF0000" />
      當然也可以使用Java程式碼建立ColorDrawable,需要注意的是Android中使用一個int型別的資料表示顏色值,通常習慣使用十六進位制格式的資料表示顏色值。一個int型別包含四個位元組,分別代表顏色的4個組成部分:透明度(Alpha)、紅(RED)、綠(GREEN)、藍(BLUE),每個部分由一個位元組(8個bit)表示,取值範圍為0~255。在xml中使用顏色時可以省略透明度(Alpha)部分,如#ff0000表示紅色。但是在程式碼中必須要明確指出透明度(Alpha)代表的資料,如果省略了就表示完全透明的顏色,例如0xFFFF0000表示紅色,而0xFF0000雖然也表示紅色,但它卻是完全透明的,也就是說當繪製到畫布上時,看不出有任何效果。         使用Java程式碼也可以建立ColorDrawable,程式碼如下:

[程式碼]java程式碼:

1 ColorDrawable drawable = new ColorDrawable(0xffff0000);
二、GradientDrawable         GradientDrawable 表示一個漸變區域,可以實現線性漸變、發散漸變和平鋪漸變效果,在Android中可以使用GradientDrawable表示很多複雜而又絢麗的介面效果。         可以使用xml定義GradientDrawable,相對於ColorDrawable型別,GradientDrawable要複雜很多,它有很多的元素組成。在xml檔案中使用shape作為根節點來建立GradientDrawable,它包含很多屬性和子節點,下面是GradientDrawable的xml文件節點結構。

[程式碼]xml程式碼:

1 <?xml version="1.0" encoding="utf-8"?>
2 <shape xmlns:android="http://schemas.android.com/apk/res/android">
3 <size /> //定義區域的大小
4 <gradient>//設定區域背景的漸變效果
5 <solid/>//設定區域的背景顏色,如果設定了solid會覆蓋gradient的效果
6 <stroke />//設定區域的邊框效果
7 <padding />//設定區域的內邊距
8 </shape>
        其中每個節點都有許多屬性需要設定,以達到不同的漸變效果。         以下是幾種不同漸變效果實現的xml檔案程式碼:

[程式碼]xml程式碼:

01 <!-- 線性漸變效果的橢圓-->
02 <?xml version="1.0" encoding="utf-8"?>
03 <shape
04 xmlns:android="http://schemas.android.com/apk/res/android"
05 android:shape="oval">
06
07 <gradient
08 android:startColor="#ff0000"
09 android:centerColor="#00ff00"
10 android:endColor="#0000ff"
11 android:angle="90" />
12 <stroke
13 android:width="3dip"
14 android:color="#fff"
15 android:dashWidth="4dip"
16 android:dashGap="5dip" />
17 </shape>
18
19 <!-- 平鋪漸變效果的圓環-->
20 <?xml version="1.0" encoding="utf-8"?>
21 <shape xmlns:android="http://schemas.android.com/apk/res/android"
22 android:shape="ring" android:innerRadiusRatio="8"
23 android:thicknessRatio="3" android:useLevel="false">
24 <gradient android:type="sweep" android:useLevel="false"
25 android:startColor="#ff0000" android:endColor="#0000ff" android:centerColor="#00ff00"/>
26 </shape>
27
28 <!-- 發散漸變效果的圓-->
29 <?xml version="1.0" encoding="utf-8"?>
30 <shape xmlns:android="http://schemas.android.com/apk/res/android"
31 android:shape="ring" android:innerRadius="0dip"
32 android:thickness="70dip" android:useLevel="false">
33 <gradient android:type="radial" android:useLevel="false" android:gradientRadius="70"
34 android:startColor="#ff0000" android:endColor="#0000ff" android:centerColor="#00ff00"/>
35 </shape>
        以下幾幅圖展示了上述三個漸變效果:

圖6-1  線性漸變效果的橢圓

圖6-2  平鋪漸變效果的圓環

圖6-3  發散漸變效果的圓 三、BitmapDrawable         BitmapDrawable 是對bitmap的一種包裝,可以設定它包裝的bitmap在BitmapDrawable區域內的繪製方式,如平鋪填充、拉伸填充或者保持圖片原始大小,也可以在BitmapDrawable區域內部使用gravity指定的對齊方式。         在xml檔案中使用bitmap作為根節點來定義BitmapDrawable。         下面的xml程式碼定義一個BitmapDrawable,同時設定了BitmapDrawable的tileMode 屬性為mirror,通過這樣設定會使用小圖片在水平和豎直方向做鏡面平鋪效果。

[程式碼]xml程式碼:

1 <?xml version="1.0" encoding="utf-8"?>
2 <bitmap xmlns:android="http://schemas.android.com/apk/res/android" 
3 android:src="@drawable/png_icon_416"
4 android:tileMode="mirror"
5 android:antialias="true"
6 android:dither="true"
7 >
8 </bitmap>
        也可以使用Java程式碼實現相同的效果,等價的Java程式碼如下:

[程式碼]java程式碼:

1 Bitmap mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.png_icon_416);
2 BitmapDrawable mBitmapDrawable = new BitmapDrawable(mBitmap);
3 mBitmapDrawable.setTileModeXY(TileMode.MIRROR, TileMode.MIRROR);
4 mBitmapDrawable.setAntiAlias(true);
5 mBitmapDrawable.setDither(true);
6 mDrawable = mBitmapDrawable;
        效果如下圖所示:

圖6-4  BitmapDrawable執行效果圖 四、NinePatchDrawable         NinePatchDrawable,“點九圖”是Andriod平臺的一種特殊的圖片格式,副檔名為:.9.png。支援Android平臺的手機型別很多,有多種不同的解析度,很多控制元件的切圖檔案在被放大拉伸後,邊角會模糊失真。在android平臺下使用“點九”圖片處理技術,可以將圖片橫向和縱向同時進行拉伸,以實現在多解析度下的完美顯示效果。點九圖片在拉伸時仍能保留影象的漸變質感和圓角的精細度。         Android SDK工具集提供了處理點九圖片的工具,可以通過draw9patch.bat執行,通過這個工具可以很容易把普通的PNG圖片處理成“點九”圖片。從它的名字也很容易理解“點九”圖的含義,其實相當於把一張PNG圖分成了9個部分(九宮格),分別為4個角,4條邊,以及一箇中間區域,4個角是不做拉伸的,所以還能一直保持圓角的清晰狀態,而2條水平邊和2條垂直邊分別只做水平和垂直拉伸,所以不會出現邊框被拉粗的情況,只有中間用黑線指定的區域做拉伸,通過這種處理方式圖片才不會失真。如圖6-5所示,對4條黑線分別做了註釋。左邊和上邊的黑線形成的矩形區域是圖片的拉伸區域,下邊和右邊形成的矩形區域是內容所在的區域。黑線可以是連續的也可以是不連續的,不過為了達到最好的顯示效果,最好使用連續的黑線。

圖6-5  點九圖片示意圖         使用了*.9.png圖片技術後,只需要採用一套介面切圖去適配不同的解析度,而且大幅減少安裝包的大小。Android FrameWork在顯示點九圖片時使用了高效的優化演算法,所示應用程式不需要專門做處理就可以實現圖片拉伸自適應,減少了程式碼量和實際開發的工作量。          在xml檔案中使用使用nine-patch作為根節點建立NinePatchDrawable。同時,也可以使用bitmap包裝點九圖片,android FrameWork會根據android:src屬性設定的圖片型別來生成對應的drawable。程式碼如下:

[程式碼]xml程式碼:

1 <?xml version="1.0" encoding="utf-8"?>
2 <nine-patch
3 xmlns:android="http://schemas.android.com/apk/res/android"
4 android:src="@drawable/droid_logo"
5 android:dither="true" />

[程式碼]xml程式碼:

1 <?xml version="1.0" encoding="utf-8"?>
2 <bitamp
3 xmlns:android="http://schemas.android.com/apk/res/android"
4 android:src="@drawable/droid_logo"
5 android:dither="true" />
        下面看一下原始點九圖片以及拉伸之後的效果:

圖6-6  原始點九圖片


圖6-7  點九圖片拉伸之後的效果         最後,需要指出的是,Android雖然可以使用Java程式碼建立NinePatchDrawable,但是極少情況會那麼做,主要的原因是由於Android SDK會在編譯工程時對點九圖片進行編譯,形成特殊格式的圖片。使用程式碼建立NinePatchDrawable時只能針對編譯過的點九圖片資源,對於沒有編譯過的點九圖片資源都當做BitmapDrawable對待。在使用點九圖片時需要注意的是,點九圖只能適用於拉伸的情況,對於壓縮的情況並不適用,如果需要適配很多解析度的螢幕時需要把點九圖做的小一點。 五、InsetDrawable         InsetDrawable 表示一個drawable嵌入到另外一個drawable內部,並且在內部留一些間距,這一點很像drawable的padding屬性,區別在於 padding表示drawable的內容與drawable本身的邊距,insetDrawable表示兩個drawable和容器之間的邊距。當控制元件需要的背景比實際的邊框小的時候比較適合使用InsetDrawable。         在xml檔案中使用inset作為跟節點定義InsetDrawable。         下面的xml定義了一個四邊邊距都為20dip的InsetDrawable,程式碼如下:

[程式碼]xml程式碼:

1 <?xml version="1.0" encoding="utf-8"?>
2 <inset xmlns:android="http://schemas.android.com/apk/res/android" 
3 android:drawable="@drawable/bitmap_bell"
4 android:insetLeft="20dp"
5 android:insetRight="20dp"
6 android:insetTop="20dp"
7 android:insetBottom="20dp"
8 >
9 </inset>
        效果如下圖所示:

圖6-8  InsetDrawable執行效果圖 六、ClipDrawable         ClipDrawable 是對一個Drawable進行剪下操作,可以控制這個drawable的剪下區域,以及相相對於容器的對齊方式,android中的進度條就是使用一個ClipDrawable實現效果的,它根據level的屬性值,決定剪下區域的大小。         在xml檔案中使用clip作為根節點定義ClipDrawable。         需要注意的是ClipDrawable是根據level的大小控制圖片剪下操作的,官方文件的note中提到:The drawable is clipped completely and not visible when the level is 0 and fully revealed when the level is 10,000。也就是level的大小從0到10000,level為0時完全不顯示,為10000時完全顯示。是用Drawable提供的setLevel(int level)方法來設定剪下區域。         下面為定義ClipDrawable的程式碼:

[程式碼]xml程式碼:

1 <?xml version="1.0" encoding="utf-8"?>
2 <clip xmlns:android="http://schemas.android.com/apk/res/android" 
3 android:clipOrientation="horizontal"
4 android:drawable="@drawable/bitmap_android"
5 android:gravity="left"
6 >
7 </clip>
        如果沒有android:drawable屬性,必須要設定一個任意型別的drawable作為子節點,程式碼如下:

[程式碼]xml程式碼:

01 <?xml version="1.0" encoding="utf-8"?>
02 <clip xmlns:android="http://schemas.android.com/apk/res/android" 
03 android:clipOrientation="horizontal"
04 android:gravity="left"
05 >
06 <bitmap 
07 android:src="@drawable/android_text"
08 android:gravity="center"
09 />
10 </clip>
        效果如下圖所示:

圖6-9  ClipDrawable執行效果圖