Drawable Animation 可以讓我們按順序加載一系列的資源來創建一個動畫。動畫的創建和傳統意義上電影膠卷的播放一樣,是通過加載不同的圖片,然后按順序進行播放來實現的。在代 碼的實現上 AnimationDrawable 類是基於 Drawable animations 來實現的。
雖然我們可以通過 AnimationDrawable 類的 API 在代碼中定義一個動畫的所有幀,但通過一個包含所有幀的 XMl 文件來完成一個動畫會更加的簡單。這個 XML 文件應該被創建在 Android 項目的 /res/drawable/ 目錄下,這樣動畫內的每一幀就會按照順序和固定的時間間隔來播放。
這個 XML 文件包含一個 <animation-list> 節點作為根節點,同時包含一系列定義了每一幀顯示資源和顯示時間的 <item> 節點作為子節點。代碼如下:
<?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="true"> <item android:drawable="@drawable/scan1" android:duration="100" /> <item android:drawable="@drawable/scan2" android:duration="100" /> <item android:drawable="@drawable/scan3" android:duration="100" /> <item android:drawable="@drawable/scan4" android:duration="100" /> </animation-list>
通過上面的代碼我們可以看到,這個動畫包含 4 幀。另外我們可以通過設置 </animation-list> 節點下的 android:oneshot 屬性來控制動畫的循環次數,如果將 android:oneshot 的屬性設置為 true,那么這個動畫只會循環一次並停留在最后一幀。如果設置為 false,那么這個動畫將會不停的循環下去。將這個文件命名文 scan.xml 並保存到項目的 /res/drawable/ 目錄下,然后它就可以當作背景圖片被添加到另一個視圖上,並被調用顯示。參見如下代碼:
package cn.sunzn.scan; import android.app.Activity; import android.graphics.drawable.AnimationDrawable; import android.os.Bundle; import android.view.Menu; import android.view.View; import android.widget.ImageView; public class MainActivity extends Activity { private ImageView scanView; private AnimationDrawable scanAnimation; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); scanView = (ImageView) findViewById(R.id.iv_scan); scanView.setBackgroundResource(R.drawable.scan); scanAnimation = (AnimationDrawable) scanView.getBackground(); } public void start(View view) { scanAnimation.start(); } public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true; } }
代碼運行效果如下:
此外,需要特別注意的是,動畫的 start() 方法不能在 Activity 的 onCreate(Bundle savedInstanceState) 方法中執行,這是因為動畫還沒有完全的填充到窗口上。如果你想立即執行動畫而不需要和用戶進行交互,那么你可以在 Activity 的 onWindowFocusChanged() 方法中來調用 start() 方法。這樣當你的應用在獲得窗口焦點的時候 start() 就會馬上被調用。代碼如下:
package cn.sunzn.scan; import android.app.Activity; import android.graphics.drawable.AnimationDrawable; import android.os.Bundle; import android.view.Menu; import android.widget.ImageView; public class MainActivity extends Activity { private ImageView scanView; private AnimationDrawable scanAnimation; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); scanView = (ImageView) findViewById(R.id.iv_scan); scanView.setBackgroundResource(R.drawable.scan); scanAnimation = (AnimationDrawable) scanView.getBackground(); } public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(true); scanAnimation.start(); } public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.activity_main, menu); return true; } }