Android動畫之一:Drawable Animation

準備寫幾篇博客講解Android的動畫,首先介紹Android動畫的整體輪廓。

Android動畫主要分爲三大類

  1. View Animation
  2. Drawable Animation
  3. Property Animation
其中Drawable Animations對大多數人來說是三者中最容易理解的,其實它就是很多書籍中提到的逐幀動畫(frame-by-frame animation)。而Property Animation和View Animation是相對比較容易混淆的,下面先講解二者的區別。
 
View Animation有兩個缺點:(1)View Animation一般只能修改組件(View Object)的部分屬性,比如:scaling(大小)和rotation(旋轉),但是無法修改組件的背景顏色。(2)View Animation使某個組件產生動畫效果移動一段距離後,比如從屏幕左側移動到右側,其實整個過程是繪製出來的效果,該組件真正的位置依然保留在左側,只有點擊左側位置才能觸發該組件。所以想真正移動某組件,需要在動畫結束後添加代碼實現。

Property Animation則沒有以上View Animation的兩個限制,Property Animation可以修改任何對象(View Object 或者 non-view Object)的任何屬性,比如大小,旋轉,顏色。並且,移動後的組件,位置也回跟隨着改變。

Android官網推薦使用Property Animation,但是View Animation也有其優點:使用方便簡單,所以當View Animation能方便快速地解決需求時,選擇它也是不錯的選擇。

以上我們對Android動畫有了一個整體的認識,接下來循序漸進,先介紹最容易學習的Drawable Animation。如上面所說,Drawable Animation是逐幀動畫,那麼使用它之前必須先定義好各個幀。我們可以通過代碼定義,也可以使用xml文件定義,一般使用後者。如下:

[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. <animation-list xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     android:oneshot="true">  
  3.     <item android:drawable="@drawable/frame_1" android:duration="200" />  
  4.     <item android:drawable="@drawable/frame_2" android:duration="200" />  
  5.     <item android:drawable="@drawable/frame_3" android:duration="200" />  
  6.     <item android:drawable="@drawable/frame_4" android:duration="200" />  
  7. </animation-list>  

其中android:oneshot=“true”表示該動畫只播放一次,等於false時則循環播放。<item/>標籤定義各個幀顯示的圖片。顯示順序依照<item/>定義順序。下面介紹一個實際場景,即平時我們常見的加載界面,
界面佈局中只有一個居中的ImageView,比較簡單,佈局文件就不列出了。相對重要的是,我們需要定義一個xml文件描述各個幀,如下:

DrawableAnimationDemo\res\drawable\loading.xml
[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <animation-list xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:oneshot="false">  
  4.     <item android:duration="100">  
  5.         <layer-list>  
  6.             <item android:drawable="@drawable/login_loading_00" />  
  7.             <item android:drawable="@drawable/login_loading_10" />  
  8.         </layer-list>  
  9.     </item>  
  10.     <item android:duration="100">  
  11.         <layer-list>  
  12.             <item android:drawable="@drawable/login_loading_01" />  
  13.             <item android:drawable="@drawable/login_loading_11" />  
  14.         </layer-list>  
  15.     </item>  
  16.     <item android:duration="100">  
  17.         <layer-list>  
  18.             <item android:drawable="@drawable/login_loading_02" />  
  19.             <item android:drawable="@drawable/login_loading_12" />  
  20.         </layer-list>  
  21.     </item>  
  22.     <item android:duration="100">  
  23.         <layer-list>  
  24.             <item android:drawable="@drawable/login_loading_03" />  
  25.             <item android:drawable="@drawable/login_loading_13" />  
  26.         </layer-list>  
  27.     </item>  
  28.     <item android:duration="100">  
  29.         <layer-list>  
  30.             <item android:drawable="@drawable/login_loading_04" />  
  31.             <item android:drawable="@drawable/login_loading_14" />  
  32.         </layer-list>  
  33.     </item>  
  34.     <item android:duration="100">  
  35.         <layer-list>  
  36.             <item android:drawable="@drawable/login_loading_05" />  
  37.             <item android:drawable="@drawable/login_loading_15" />  
  38.         </layer-list>  
  39.     </item>  
  40.     <item android:duration="100">  
  41.         <layer-list>  
  42.             <item android:drawable="@drawable/login_loading_06" />  
  43.             <item android:drawable="@drawable/login_loading_16" />  
  44.         </layer-list>  
  45.     </item>  
  46.     <item android:duration="100">  
  47.         <layer-list>  
  48.             <item android:drawable="@drawable/login_loading_07" />  
  49.             <item android:drawable="@drawable/login_loading_17" />  
  50.         </layer-list>  
  51.     </item>  
  52.     <item android:duration="100">  
  53.         <layer-list>  
  54.             <item android:drawable="@drawable/login_loading_08" />  
  55.             <item android:drawable="@drawable/login_loading_18" />  
  56.         </layer-list>  
  57.     </item>  
  58.     <item android:duration="100">  
  59.         <layer-list>  
  60.             <item android:drawable="@drawable/login_loading_09" />  
  61.             <item android:drawable="@drawable/login_loading_19" />  
  62.         </layer-list>  
  63.     </item>  
  64. </animation-list>  

以上xml文件與前面一個xml文件不大同,多了一個<layer-list/>標籤,該標籤用法很簡單,<layer-list/>內包含的圖片將層疊起來,在同一幀中一起顯示。如下:

 +   =  


再看主界面的activity文件,如下:

DrawableAnimationDemo\src\com\example\drawableanimationdemo\MainActivity.java
[java] view plain copy
 在CODE上查看代碼片派生到我的代碼片
  1. public class MainActivity extends Activity {  
  2.       
  3.     private AnimationDrawable loadingAnimation;  
  4.   
  5.     @Override  
  6.     protected void onCreate(Bundle savedInstanceState) {  
  7.         super.onCreate(savedInstanceState);  
  8.         requestWindowFeature(Window.FEATURE_NO_TITLE);  
  9.         setContentView(R.layout.activity_main);  
  10.         //將該逐幀xml文件設置爲ImageView的背景  
  11.         ImageView loadingImg = (ImageView) findViewById(R.id.loading);  
  12.         loadingImg.setBackgroundResource(R.drawable.loading);  
  13.         loadingAnimation = (AnimationDrawable) loadingImg.getBackground();  
  14.     }  
  15.   
  16.     /** 
  17.      * 觸摸屏幕,結束動畫 
  18.      */  
  19.     public boolean onTouchEvent(MotionEvent event) {  
  20.         if (event.getAction() == MotionEvent.ACTION_DOWN) {  
  21.             loadingAnimation.stop();  
  22.             return true;  
  23.         }  
  24.         return super.onTouchEvent(event);  
  25.     }  
  26.   
  27.     /** 
  28.      * activity顯示到屏幕則開啓動畫 
  29.      */  
  30.     @Override  
  31.     public void onWindowFocusChanged(boolean hasFocus) {  
  32.         // TODO Auto-generated method stub  
  33.         super.onWindowFocusChanged(hasFocus);  
  34.         if (hasFocus)  
  35.             loadingAnimation.start();  
  36.     }  
  37.   
  38. }  

效果圖如下,其中圖片素材取材於OSchina的開源項目。



以上代碼實現的功能是:activity一啓動,則動畫開始,觸摸屏幕時動畫停止,代碼比較容易理解,唯一需要注意的是,不能在onCreate()方法中調用AnimationDrawable的start()方法,因爲此時AnimationDrawable還未真正加載到界面中。所以,如果想啓動界面就自動運行動畫,可以在OnWindowFocusChanged(boolean hasFocus)中啓動動畫。

好了,只要掌握了這個例子,日常開發中Drawable Animation需要的知識已經足夠。最後附上源碼免費下載。

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