Drawable資源

 在Android應用中,常常會用到Drawable資源,比如圖片資源等,在Android開發中我們是用Drawable類來Drawable類型資源的。

Drawable資源一般存儲在應用程序目錄的\res\drawable目錄下,當然依據分辨率的高低可以分別存儲不同分辨率的資源到如下幾個目錄:

\res\drawable-hdpi

\res\drawable-mdpi

\res\drawable-xhdpi

\res\drawable-xxhdpi

其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(R.id.ImageView1);
imageView.setImageResource(R.drawable.drawablefilename);


StateListDrawable資源

StateListDrawable內可以分配一組Drawable資源,StateListDrawable 被定義在一個XML文件中,以 <selector>元素起始。其內部的每一個Drawable資源內嵌在<item>元素中。

當StatListDrawable資源作爲組件的背景或者前景Drawable資源時,可以隨着組件狀態的變更而自動切換相對應的資源,例如,一個Button可以處於不同的狀態(按鈕按下、獲取焦點)

我們可以使用一個StateListDrawable資源,來提供不同的背景圖片對於每一個狀態。,當組件的狀態變更時,會自定向下遍歷StateListDrawable對應的xml文件來查找第一個匹配的Item。

StatListDrawable資源所支持的組件狀態如下圖所示:

android:state_selected是選中
android:state_focused
是獲得焦點
android:state_pressed
是點擊
android:state_enabled
是設置是否響應事件,指所有事件

以下代碼片段是一個StateListDrawable資源的XML文件描述樣例:

XML 文件存儲在: res/drawable/button_statelist.xml:

<?xmlversion="1.0"encoding="utf-8"?><selectorxmlns:android="http://schemas.android.com/apk/res/android"><itemandroid:state_pressed="true"android:drawable="@drawable/button_pressed"/><!-- pressed --><itemandroid:state_focused="true"android:drawable="@drawable/button_focused"/><!-- focused --><itemandroid:state_hovered="true"android:drawable="@drawable/button_focused"/><!-- hovered --><itemandroid:drawable="@drawable/button_normal"/><!-- default --></selector>

以下是Button的Layout文件:

<Buttonandroid:layout_height="wrap_content"android:layout_width="wrap_content"android:background="@drawable/button"/>

當然我們也可以通過代碼來設置Button的背景圖片:

Button imageButton=(Button)findViewById(R.id.imageButton);

imageButton.setBackgroundResource(R.drawable.button_statelist);

在ListView中使用:
1.方法一:在listview中配置android:listSelector="@drawable/xxx
或者在listview的item中添加屬性android:background="@drawable/xxx"

2.方法二:Drawable drawable = getResources().getDrawable(R.drawable.xxx);  
       ListView.setSelector(drawable);但是這樣會出現列表有時候爲黑的情況,需要加上:android:cacheColorHint="@android:color/transparent"使其透明。


參數說明:

其中selected和focused的區別有如下幾點:

      1,我們通過查看setSelected()方法,來獲取相關信息。

        SDK中對setSelected()方法----對於與selected狀態有如下說明:

             public void setSelected (boolean selected)

             Since: APILevel 1

             Changes the selection state of this view. Aview can be selected or not. Note that selection is not the same as

        focus. Views are typically selected in the context of an AdapterView like ListView or GridView ;the selected view is 

        the view that is highlighted.

            Parameters selected   true if the view must be selected, false otherwise


           由以上可知:selected不同於focus狀態,通常在AdapterView類羣下例如ListView或者GridView會使某個View處於

     selected狀態,並且獲得該狀態的View處於高亮狀態。

 

    2、一個窗口只能有一個視圖獲得焦點(focus),而一個窗口可以有多個視圖處於”selected”狀態中。

 

      總結:focused狀態一般是由按鍵操作引起的;

                pressed狀態是由觸摸消息引起的;

                selected則完全是由應用程序主動調用setSelected()進行控制。

 

      例如:當我們觸摸某個控件時,會導致pressed狀態改變;獲得焦點時,會導致focus狀態變化。於是,我們可以通過這種

   更新後狀態值去更新我們對應的Drawable對象了。

ShapeDrawable資源

ShapeDrawable資源繪製一個特定的形狀,比如矩形、橢圓等。如果你想自己動態的繪製二位圖形,那麼我們就可以使用ShapeDrawable資源對象,用ShapeDrawable,我們可以繪製我們所能想象的形狀。。一個ShapeDrawable 需要一個Shape對象來管理呈現資源到UI Screen,如果沒有Shape設置,那麼會默認使用RectShape對象。

ShapeDrawable 被定義在一個XML文件中,以 <shape> 元素起始。其內部的每一個Drawable資源內嵌在<item>元素中

以下代碼片段便是一個ShapeDrawable的XML定義

<?xmlversion="1.0"encoding="UTF-8"?><shapexmlns:android="http://schemas.android.com/apk/res/android"android:shape="oval"><!-- 定義填充漸變顏色 --><gradientandroid:startColor="#00f"android:endColor="#00f"android:angle="45"android:type="sweep"/><!-- 設置內填充 --><paddingandroid:left="7dp"android:top="7dp"android:right="7dp"android:bottom="7dp"/>
    <!-- 設置背景色
    <solid android:color="#00f"/>
    -->
    <!-- 設置圓角矩形 
<cornersandroid:radius="8dp"/></shape>

參數說明:

<!-- 

  android:shape=["rectangle" | "oval" | "line" | "ring"]

  shape的形狀,默認爲矩形,可以設置爲矩形(rectangle)、橢圓形(oval)、線性形狀(line)、環形(ring)

  下面的屬性只有在android:shape="ring時可用:

  android:innerRadius 尺寸,內環的半徑。

  android:innerRadiusRatio 浮點型,以環的寬度比率來表示內環的半徑,

  例如,如果android:innerRadiusRatio,表示內環半徑等於環的寬度除以5,這個值是可以被覆蓋的,默認爲9.

  android:thickness 尺寸,環的厚度

  android:thicknessRatio 浮點型,以環的寬度比率來表示環的厚度,例如,如果android:thicknessRatio="2",

  那麼環的厚度就等於環的寬度除以2。這個值是可以被android:thickness覆蓋的,默認值是3.

  android:useLevel boolean值,如果當做是LevelListDrawable使用時值爲true,否則爲false.

  -->

<shape

    xmlns:android="http://schemas.android.com/apk/res/android"

    android:shape="rectangle">


<!--

      圓角 

      android:radius   整型 半徑

      android:topLeftRadius   整型 左上角半徑

      android:topRightRadius   整型 右上角半徑

      android:bottomLeftRadius 整型 左下角半徑

      android:bottomRightRadius 整型 右下角半徑

     -->

<corners  

        android:radius="8dp"

        android:topLeftRadius="5dp"

        android:topRightRadius="15dp"

        android:bottomLeftRadius="20dp"

        android:bottomRightRadius="25dp"  

        />


<!--

        漸變色

        android:startColor  顏色值 起始顏色

        android:endColor    顏色值 結束顏色

        android:centerColor 整型   漸變中間顏色,即開始顏色與結束顏色之間的顏色

        android:angle       整型   漸變角度(PS:當angle=0時,漸變色是從左向右。 然後逆時針方向轉,當angle=90時爲從下往上。angle必須爲45的整數倍)

        android:type        ["linear" | "radial" | "sweep"] 漸變類型(取值:linear、radial、sweep)

                            linear 線性漸變,這是默認設置

                            radial 放射性漸變,以開始色爲中心。

                            sweep 掃描線式的漸變。

       android:useLevel   ["true" | "false"] 如果要使用LevelListDrawable對象,就要設置爲true。設置爲true無漸變。false有漸變色

       android:gradientRadius 整型 漸變色半徑.當 android:type="radial" 時才使用。單獨使用 android:type="radial"會報錯。

       android:centerX     整型   漸變中心X點座標的相對位置

       android:centerY   整型   漸變中心Y點座標的相對位置

    -->

    <gradient

        android:startColor="#FFFF0000"

        android:endColor="#80FF00FF"

        android:angle="45"

        /> 

        

    <!--

          內邊距,即內容與邊的距離 

          android:left   整型 左內邊距

          android:top   整型 上內邊距

          android:right   整型 右內邊距

          android:bottom 整型 下內邊距

      -->

     <padding 

         android:left="10dp"

         android:top="10dp"

         android:right="10dp"

         android:bottom="10dp"

         />

     

    <!-- 

       size 大小

       android:width 整型 寬度

       android:height 整型 高度

    -->

    <size

        android:width="600dp"

        />

    

    <!--

        內部填充

        android:color 顏色值 填充顏色

    -->

    <solid 

        android:color="#ffff9d77"

        />

    

     <!--

         描邊

         android:width 整型 描邊的寬度

         android:color 顏色值 描邊的顏色

         android:dashWidth 整型 表示描邊的樣式是虛線的寬度, 值爲0時,表示爲實線。值大於0則爲虛線。

         android:dashGap   整型 表示描邊爲虛線時,虛線之間的間隔 即“ - - - - ”

     -->

     <stroke 

        android:width="2dp"

        android:color="#dcdcdc"  

        /> 


我們可以用ShapeDrawable 來設置組件的背景色(用setBackgroundDrawable()方法),如上的代碼片段可設置一個TextEdit的背景色爲藍色的橢圓形狀。當然我們也可以繪製自定義的View

我們構建自定義形狀的View時,由於ShapeDrawable 有其自己的draw()方法,我們可以構建一個View視圖的子類,然後override View.onDraw()方法,如下代碼片段是一個樣例:

publicclass 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);
      }

      protectedvoid onDraw(Canvas canvas) {
      mDrawable.draw(canvas);
      }
    }

基於上述代碼我們可以在我們的Activity中編程的構建自定義視圖:

CustomDrawableView mCustomDrawableView;

      protectedvoid 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資源:

<?xmlversion="1.0"encoding="utf-8"?><clipxmlns:android="http://schemas.android.com/apk/res/android"android:drawable="@drawable/android"android:clipOrientation="horizontal"android:gravity="left"/>

下面的ImageView佈局文件應用Clipdrawable資源:

 

<ImageViewandroid: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通過定義一系列的Drawable對象構建一個基於幀的動畫(frame-by-frame animations),可以被用來作爲視圖的背景色。

最簡單的構建一個幀動畫是在XML文件中構建一個動畫,我們可以設定動畫作爲視圖的背景色,通過調用AnimationDrawable.start()方法來運行動畫。

如下代碼片段是一個AnimationDrawable資源的XML文件,資源文件位置:res\drawable\spin_animation.xml

<animation-listxmlns:android="http://schemas.android.com/apk/res/android"android:oneshot="true"><itemandroid:drawable="@drawable/rocket_thrust1"android:duration="200"/><itemandroid:drawable="@drawable/rocket_thrust2"android:duration="200"/><itemandroid: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文檔。


發佈了15 篇原創文章 · 獲贊 4 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章