Android仿微信開啟紅包動畫(逐幀動畫)
Frame Animation(逐幀動畫):
逐幀動畫(Frame-by-frame Animations)從字面上理解就是一幀挨著一幀的播放圖片,就像放電影一樣。和補間動畫一樣可以通過xml實現也可以通過java程式碼實現。接下來藉助目前專案中的一個開獎的動畫來總結如何使用。實現效果如下:
具體實現過程:
1.)在res/drawable目錄下一個檔案lottery_animlist.xml,內容如下:
<?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:android="http://schemas.android.com/apk/res/android"android:oneshot="false"> <item android:drawable="@mipmap/lottery_1" android:duration="200" /> <item android:drawable="@mipmap/lottery_2" android:duration="200" /> <item android:drawable="@mipmap/lottery_3" android:duration="200"/> <item android:drawable="@mipmap/lottery_4" android:duration="200" /> <item android:drawable="@mipmap/lottery_5" android:duration="200" /> <item android:drawable="@mipmap/lottery_6" android:duration="200" /> </animation-list>
根節點是animation-list(動畫列表),裡面有一個或者多個item節點組成,oneshot屬性表示是否只播放一次,true表示只會播放一次,false表示一直迴圈播放,內部用item節點宣告一個動畫幀,android:drawable指定此幀動畫所對應的圖片資源,android:druation代表此幀持續的時間,整數,單位為毫秒。
2.)用ImageView控制元件作為動畫載體來顯示動畫
<ImageView android:id="@+id/animation_iv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_margin="10dp" android:src="@drawable/lottery_animlist" />
這個時候我們執行一下,發現動畫沒有執行而是停留在第一幀,那是因為AnimationDrawable播放動畫是依附在window上面的,而在Activity onCreate方法中呼叫時Window還未初始化完畢,所有才會停留在第一幀,要想實現播放必須在onWindowFocusChanged中新增如下程式碼:
imageView.setImageResource(R.drawable.lottery_animlist); AnimationDrawable animationDrawable = (AnimationDrawable) imageView.getDrawable(); animationDrawable.start();
如果想要停止播放動畫可以呼叫AnimationDrawable的stop方法
imageView.setImageResource(R.drawable.lottery_animlist); AnimationDrawable animationDrawable = (AnimationDrawable) imageView.getDrawable(); animationDrawable.stop();
3.)純Java程式碼實現方式
AnimationDrawable anim = new AnimationDrawable(); for (int i = 1; i <= 6; i++) { int id = getResources().getIdentifier("lottery_" + i, "mipmap", getPackageName()); Drawable drawable = getResources().getDrawable(id); anim.addFrame(drawable, 200); } anim.setOneShot(false); imageView.setImageDrawable(anim); anim.start();
4.)AnimationDrawable 幾個常見的api
-
void start()
- 開始播放動畫 -
void stop()
- 停止播放動畫 -
addFrame(Drawable frame, int duration)
- 新增一幀,並設定該幀顯示的持續時間 -
void setOneShoe(boolean flag)
- false為迴圈播放,true為僅播放一次 -
boolean isRunning()
- 是否正在播放
總結:
Frame Animation(逐幀動畫)相對來說比較簡單,但是在實際開發中使用的頻率還是比較高的。希望以這個小例子能夠掌握逐幀動畫,但是逐幀動畫只能實現比較小的動畫效果,如果複雜而且幀數比較多的動畫不太建議使用逐幀動畫,一方面是因為會造成OOM,另一方面會顯得很卡,如果真是超級複雜的動畫的話建議選擇雙緩衝繪製View來實現。