標籤雲

搜尋此網誌

2013/08/25

Animation - DrawableContainer 的子類別與 TransitionDrawable

在前篇 Animation - View Animations 曾經有介紹過在 res/drawable/ 定義一個 xml 去做一個類似 gif 檔的逐格動畫的方法
當時使用的類別就是 AnimationDrawable
這次來稍微詳細一點介紹它跟它的兩位兄弟
並且介紹同樣在 android.graphics.drawable 這個 package 下的另一個類別 TransitionDrawable

AnimationDrawable 是繼承自 android.graphics.drawable.DrawableContainer
(DrawableContainer 這個類別顧名思義就是可以用來放數個 Drawable 的容器)
同樣繼承自 DrawableContainer 的還有兩個兄弟 LevelListDrawable 跟 StateListDrawable

LevelListDrawable 是利用 addLevel(int low, int high, Drawable drawable) 加入 Drawable
再利用 setLevel(int) 改變顯示
(它會自己去找大於或等於傳入值的 int 去運作)
可以用來做電池電量圖示或 wifi 訊號圖示
也可以用 xml 設定

用官方給的簡單範例code來快速帶過吧

  <item android:maxLevel="0" android:drawable="@drawable/ic_wifi_signal_1" />
  <item android:maxLevel="1" android:drawable="@drawable/ic_wifi_signal_2" />
  <item android:maxLevel="2" android:drawable="@drawable/ic_wifi_signal_3" />
  <item android:maxLevel="3" android:drawable="@drawable/ic_wifi_signal_4" />


至於 StateListDrawable 我們也一定接觸過
因為我們用來設定 component 狀態(如 Button)的 xml
就會被 compile 成 StateListDrawable
相關屬性如下:


    <item
        android:drawable="@[package:]drawable/drawable_resource"
        android:state_pressed=["true" | "false"]
        android:state_focused=["true" | "false"]
        android:state_hovered=["true" | "false"]
        android:state_selected=["true" | "false"]
        android:state_checkable=["true" | "false"]
        android:state_checked=["true" | "false"]
        android:state_enabled=["true" | "false"]
        android:state_activated=["true" | "false"]
        android:state_window_focused=["true" | "false"] />

一樣用官方範例來帶過


    <item android:state_pressed="true"
          android:drawable="@drawable/button_pressed" /> 
    <item android:state_focused="true"
          android:drawable="@drawable/button_focused" /> 
    <item android:state_hovered="true"
          android:drawable="@drawable/button_focused" /> 
    <item android:drawable="@drawable/button_normal" /> 


越扯越遠
還是趕快回到正題好了

AnimationDrawable 逐格動畫用是用 void addFrame(Drawable frame, int duration) 這個 method 去新增每個 frame
然後利用 isRunning(), start() 跟 stop() 等方法去操控

在 DevBytes: KeyFrame Animations 影片裡
是自己繪製每格的 bitmap 然後 new BitmapDrawable(Resources res, Bitmap bitmap) 去 addFrame
這個簡單的方式去 demo
有興趣的自己去看影片嚕


接著說說 TransitionDrawable 吧
TransitionDrawable 繼承自 android.graphics.drawable.LayerDrawable
作用是讓兩個 Drawable 作淡入淡出轉換

建構子為 TransitionDrawable(Drawable[] layers)
也就是說建立實體時就需要傳入一個 Drawable array

方法不多所以全部列出如下:
void draw(Canvas canvas) //在畫定範圍(setBounds)內把畫面 Draw 出來,接受父類裡面 setAlpha, setColorFilter 之類的效果套用

void startTransition(int durationMillis)
void resetTransition()
void reverseTransition(int duration) //從目前的狀態倒放回去

void setCrossFadeEnabled(boolean enabled) //交叉淡入淡出,預設是 false,即第二張在第一張上面 fade in,若為 true 則第二張與第一張的 alpha 值是相反
boolean isCrossFadeEnabled()

使用 xml 設定的話其 element 為 <transition>
相關屬性如下:


    <item
        android:drawable="@[package:]drawable/drawable_resource"
        android:id="@[+][package:]id/resource_name"
        android:top="dimension"
        android:right="dimension"
        android:bottom="dimension"
        android:left="dimension" />

一樣貼上官方範例 code 作示範


    
    

ImageButton button = (ImageButton) findViewById(R.id.button);
TransitionDrawable drawable = (TransitionDrawable) button.getDrawable(); //該 ImageButton 已將 src 屬性設為上面的 xml
drawable.startTransition(500); //500 毫秒

相關資料:

YouTube - DevBytes: CrossFading Animations
YouTube - DevBytes: KeyFrame Animations

developer.android.com - AnimationDrawable
developer.android.com - LevelListDrawable
developer.android.com - StateListDrawable

developer.android.com - API Guides - Drawable Resourcese

developer.android.com - LayerDrawable
developer.android.com - TransitionDrawable

沒有留言: