Android ApiDemos示例解析(52):Graphics->AnimateDrawables

這個例子的示例代碼有ProxyDrawable.java,AnimateDrawable.java和AnimateDrawables.java。

Android 包android.graphics.drawable 中定義瞭一個Drawable 為所有Drawable的抽象基類。表示一個“可以繪制在屏幕的對象”。通常的情況下是從資源文件中讀取各種不同類型的Drawable。和View不同的是Drawable不能接受處理事件不能和用戶交互。Android自定義的Drawable有下列幾種類型:

Bitmap: 代表PNG或是JPEG圖像。
Nine Patch: PNG圖像的一種擴展用法,多用來定義按鈕邊框,可以縮放。
Shape: 簡單的矢量幾何圖形。
Layers: drawable 的集合組件,可以由多層Drawable疊加組合而成。
States: drawable 的集合組件,可以從多個Drawable選擇其一(一種狀態)。
Levels: drawable的集合組件, 可以根據Drawable的Level屬性選擇其一。
Scale: drawable的集合組件, 使用一個Drawable但可以根據當前Level縮放Drawable。
此外也可以自定義Drawable,本例自定義瞭ProxyDrawable ,處理添加瞭一些檢測基本上是和它代理的Drawable提供同樣的功能。AnimateDrawable 是真正使用的自定義Drawable,它使用瞭Animation類來提供動畫效果。

Android動畫分為兩種類型,一種稱為“tweened”動畫,主要是通過坐標變換:平移,旋轉,縮放,色彩變化來顯示動畫效果,另外一種為“幀動畫”由一幅一幅的圖像連續顯示而成。“tweened”動畫由android.view.animation包中定義類來完成,而“幀動畫”主要由AnimationDrawable 實現。

下面看看AnimateDrawable的void draw(Canvas canvas)實現

[java] 
@Override 
public void draw(Canvas canvas) { 
 Drawable dr = getProxy(); 
 if (dr != null) { 
 int sc = canvas.save(); 
 Animation anim = mAnimation; 
 if (anim != null) { 
 anim.getTransformation( 
 AnimationUtils.currentAnimationTimeMillis(), 
 mTransformation); 
 canvas.concat(mTransformation.getMatrix()); 
 } 
 dr.draw(canvas); 
 canvas.restoreToCount(sc); 
 } 

@Override
public void draw(Canvas canvas) {
 Drawable dr = getProxy();
 if (dr != null) {
 int sc = canvas.save();
 Animation anim = mAnimation;
 if (anim != null) {
 anim.getTransformation(
 AnimationUtils.currentAnimationTimeMillis(),
 mTransformation);
 canvas.concat(mTransformation.getMatrix());
 }
 dr.draw(canvas);
 canvas.restoreToCount(sc);
 }
}
canvas.save()和canvas.restoreToCount(sc);是用來保存和回復Canvas的狀態(Maxtrix等屬性),因為我們需要修改Canvas的Matrix屬性,canvas.concat方法都會和當前Canvas的Matrix進行矩陣運算,如果我麼不保存之前的Matrix屬性,每次都會很上次矩陣運算的結果相乘,對應本例來說,每次平移的距離會越來越大。

註:對於AnimateDrawable來說,Animation可以是任意類型:平移,縮放,旋轉等。AnimateDrawables 中使用的是平移TranslateAnimation。

[java] 
Animation an = new TranslateAnimation(0, 100, 0, 200); 
an.setDuration(2000); 
an.setRepeatCount(-1); 
an.initialize(10, 10, 10, 10); 
Animation an = new TranslateAnimation(0, 100, 0, 200);
an.setDuration(2000);
an.setRepeatCount(-1);
an.initialize(10, 10, 10, 10);
平移變換動畫,定義瞭X,Y方向變化的范圍X[0,100] ,Y[0,200],持續時間2秒。setRepeatCount為-1表示無限次。an.initialize(10, 10, 10, 10)對於TranslateAnimation來說無多大實際意義,隻要void initialize(int width, int height, int parentWidth, int parentHeight) 中width,height不為0即可。

AnimateDrawables 的onDraw 方法:

[java] 
@Override protected void onDraw(Canvas canvas) { 
 canvas.drawColor(Color.WHITE); 
  
 mDrawable.draw(canvas); 
 invalidate(); 

@Override protected void onDraw(Canvas canvas) {
 canvas.drawColor(Color.WHITE);
 
 mDrawable.draw(canvas);
 invalidate();
}
onDraw裡面又調用瞭invalidate方法,又會觸發onDraw,這樣動畫就會一直運行下去。

 

 

作者:mapdigit
 

發佈留言