在Android應用中,常常會用到Drawable資源,比如圖片資源等,在Android開發中我們是用Drawable類來Drawable類型資源的。
Drawable資源一般存儲在應用程序目錄的\res\drawable目錄下,當然依據分辨率的高低可以分別存儲不同分辨率的資源到如下幾個目錄:
\res\drawable-hdpi
\res\drawable-ldpi
\res\drawable-mdpi
\res\drawable-xdpi
其SDK文檔中聲明如下:
我們看到Drawable是一個抽象類(abstract class),它有好多子類(SubClass)來操作具體類型的資源,比如BitmapDrawable是用來操作位圖,ColorDrawable用來操作顏色,
ClipDrawable用來操作剪切板等。
圖片資源
圖片資源是簡單的Drawable資源,目前Android支持的圖片格式有:gif、png、jpg等。我們只需要把圖片資源放置到\res\drawable目中,那么在編譯后的R.java類中就會生成圖片資源的資源ID
我們在程序中就可以通過調用相關的方法來獲取圖片資源(程序中如果要訪問drawable_resource_file_name,那么可以如此:[packagename].R.drawable.drawable_resource_file_name)。
注:Android中drawable中的資源名稱有約束,必須是: [a-z0-9_.](即:只能是字母數字及_和.),而且不能以數字開頭,否則編譯會報錯: Invalid file name: must contain only [a-z0-9_.]
以下代碼片段演示了如何訪問一個圖片資源(資源名稱drawablefilename):
ImageView imageView=(ImageView)findViewById(com.jeriffe.app.R.id.ImageView1); imageView.setImageResource(com.jeriffe.app.R.drawable.drawablefilename);
StateListDrawable資源
StateListDrawable內可以分配一組Drawable資源,StateListDrawable 被定義在一個XML文件中,以 <selector>元素起始。其內部的每一個Drawable資源內嵌在<item>元素中。
當StatListDrawable資源作為組件的背景或者前景Drawable資源時,可以隨着組件狀態的變更而自動切換相對應的資源,例如,一個Button可以處於不同的狀態(按鈕按下、獲取焦點)
我們可以使用一個StateListDrawable資源,來提供不同的背景圖片對於每一個狀態。,當組件的狀態變更時,會自定向下遍歷StateListDrawable對應的xml文件來查找第一個匹配的Item。
StatListDrawable資源所支持的組件狀態如下圖所示:
以下代碼片段是一個StateListDrawable資源的XML文件描述樣例:
XML 文件存儲在: res/drawable/button_statelist.xml:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true" android:drawable="@drawable/button_pressed" /> <!-- pressed --> <item android:state_focused="true" android:drawable="@drawable/button_focused" /> <!-- focused --> <item android:state_hovered="true" android:drawable="@drawable/button_focused" /> <!-- hovered --> <item android:drawable="@drawable/button_normal" /> <!-- default --> </selector>
以下是Button的Layout文件:
<Button android:layout_height="wrap_content" android:layout_width="wrap_content" android:background="@drawable/button" />
當然我們也可以通過代碼來設置Button的背景圖片:
Button imageButton=(Button)findViewById(R.id.imageButton); imageButton.setBackgroundResource(com.jeriffe.app.R.drawable.button_statelist);
ShapeDrawable資源
ShapeDrawable資源繪制一個特定的形狀,比如矩形、橢圓等。如果你想自己動態的繪制二位圖形,那么我們就可以使用ShapeDrawable資源對象,用ShapeDrawable,我們可以繪制我們所能想象的形狀。。一個ShapeDrawable 需要一個Shape對象來管理呈現資源到UI Screen,如果沒有Shape設置,那么會默認使用RectShape對象。
ShapeDrawable 被定義在一個XML文件中,以 <shape> 元素起始。其內部的每一個Drawable資源內嵌在<item>元素中
以下代碼片段便是一個ShapeDrawable的XML定義
<?xml version="1.0" encoding="UTF-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="oval"> <!-- 定義填充漸變顏色 --> <gradient android:startColor="#00f" android:endColor="#00f" android:angle="45" android:type="sweep"/> <!-- 設置內填充 --> <padding android:left="7dp" android:top="7dp" android:right="7dp" android:bottom="7dp" /> <!-- 設置圓角矩形 --> <corners android:radius="8dp" /> </shape>
我們可以用ShapeDrawable 來設置組件的背景色(用setBackgroundDrawable()方法),如上的代碼片段可設置一個TextEdit的背景色為藍色的橢圓形狀。當然我們也可以繪制自定義的View
我們構建自定義形狀的View時,由於ShapeDrawable 有其自己的draw()方法,我們可以構建一個View視圖的子類,然后override View.onDraw()方法,如下代碼片段是一個樣例:
public class CustomDrawableView extends View { private ShapeDrawable mDrawable; public CustomDrawableView(Context context) { super(context); int x = 10; int y = 10; int width = 300; int height = 50; mDrawable = new ShapeDrawable(new OvalShape()); mDrawable.getPaint().setColor(0xff74AC23); mDrawable.setBounds(x, y, x + width, y + height); } protected void onDraw(Canvas canvas) { mDrawable.draw(canvas); } }
基於上述代碼我們可以在我們的Activity中編程的構建自定義視圖:
CustomDrawableView mCustomDrawableView;
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mCustomDrawableView = new CustomDrawableView(this); setContentView(mCustomDrawableView); }
當然我們也可以使用XML文件來描述:自定義的Drawable類必須重載view (Context, AttributeSet) 構造函數。接着我們添加Layout文件如下:
<com.example.shapedrawable.CustomDrawableView android:layout_width="fill_parent" android:layout_height="wrap_content" />
ClipDrawable
ClipDrawable資源定義在一個XML中,表示裁剪(Clips)一個其他資源基於ClipDrawable資源的Level。你可以控制裁剪的Drawable的寬度高度及gravity屬性,ClipDrawable常常被用來作為一個progressbars的實現。
以下樣例是一個ClipDrawable資源:
<?xml version="1.0" encoding="utf-8"?> <clip xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/android" android:clipOrientation="horizontal" android:gravity="left" />
下面的ImageView布局文件應用Clipdrawable資源:
<ImageView android:id="@+id/image" android:background="@drawable/clip" android:layout_height="wrap_content" android:layout_width="wrap_content" />
下面的代碼獲取drawable並且增加其裁剪,以便於漸增的顯示圖像
ImageView imageview = (ImageView) findViewById(R.id.image); ClipDrawable drawable = (ClipDrawable) imageview.getDrawable(); drawable.setLevel(drawable.getLevel() + 1000);
當然我們可以使用一個Timer來實現圖片的漸增顯示。
注意: 默認的Level值是0,表示圖片被這個裁剪,故圖片是不可見的。當值達到10000是代碼裁剪為0,圖片可以完全顯示。
AnimationDrawable
AnimationDrawable
AnimationDrawable通過定義一系列的Drawable對象構建一個基於幀的動畫(frame-by-frame animations),可以被用來作為視圖的背景色。
最簡單的構建一個幀動畫是在XML文件中構建一個動畫,我們可以設定動畫作為視圖的背景色,通過調用AnimationDrawable.start()方法來運行動畫。
如下代碼片段是一個AnimationDrawable資源的XML文件,資源文件位置:res\drawable\spin_animation.xml
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="true"> <item android:drawable="@drawable/rocket_thrust1" android:duration="200" /> <item android:drawable="@drawable/rocket_thrust2" android:duration="200" /> <item android:drawable="@drawable/rocket_thrust3" android:duration="200" /> </animation-list>
我們可以看到,AnimationDrawable資源文件以<animation-list>元素為根,包含一系列的<Item>節點,每一個節點定義了一個幀(frame)及持續時常。
上述動畫運行了3個幀,通過設置android:oneshot 屬性(attribute)為true,動畫會循環一次並停留在最后一幀,如果為false那么會輪詢(loop)的運行動畫
我們可以通過編碼來加載播放動畫:
// Load the ImageView that will host the animation and
// set its background to our AnimationDrawable XML resource. ImageView img = (ImageView)findViewById(R.id.spinning_wheel_image); img.setBackgroundResource(R.drawable.spin_animation); // Get the background, which has been compiled to an AnimationDrawable object. AnimationDrawable frameAnimation = (AnimationDrawable) img.getBackground(); // Start the animation (looped playback by default). frameAnimation.start();
注意:AnimationDrawable. start()方法不能夠在Activity的onCreate()方法中調用,因為AnimationDrawable還未完全的附加(attached)到Window,如果你不需要交互而立即播放動畫,那么可以在onWindowFocusChanged() 方法中,這個方法會在你的Activity Windows獲取焦點是觸發。
結束語
至此我們的Drawable資源就介紹完了,當然還有好多的Drawable子類未進行介紹,感興趣的可以關注SDK文檔。



