Android動畫之逐幀動畫(Frame Animation)實例詳解
本文實例分析了Android動畫之逐幀動畫。分享給大家供大家參考,具體如下:
在開始實例講解之前,先引用官方文檔中的一段話:
Frame動畫是一系列圖片按照一定的順序展示的過程,和放電影的機制很相似,我們稱為逐幀動畫。Frame動畫可以被定義在XML文件中,也可以完全編碼實現(xiàn)。
如果被定義在XML文件中,我們可以放置在/res下的anim或drawable目錄中(/res/[anim | drawable]/filename.xml),文件名可以作為資源ID在代碼中引用;如果由完全由編碼實現(xiàn),我們需要使用到AnimationDrawable對象。
如果是將動畫定義在XML文件中的話,語法如下:
<?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot=["true" | "false"] > <item android:drawable="@[package:]drawable/drawable_resource_name" android:duration="integer" /> </animation-list>
需要注意的是:
<animation-list>元素是必須的,并且必須要作為根元素,可以包含一或多個<item>元素;android:onshot如果定義為true的話,此動畫只會執(zhí)行一次,如果為false則一直循環(huán)。
<item>元素代表一幀動畫,android:drawable指定此幀動畫所對應(yīng)的圖片資源,android:druation代表此幀持續(xù)的時間,整數(shù),單位為毫秒。
文檔接下來的示例我就不在解說了,因為接下來我們也要結(jié)合自己的實例演示一下這個過程。
我們新建一個名為anim的工程,將四張連續(xù)的圖片分別命名為f1.png,f2.png,f3.png,f4.png,放于drawable目錄,然后新建一個frame.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="@drawable/f1" android:duration="300" /> <item android:drawable="@drawable/f2" android:duration="300" /> <item android:drawable="@drawable/f3" android:duration="300" /> <item android:drawable="@drawable/f4" android:duration="300" /> </animation-list>
我們可以將frame.xml文件放置于drawable或anim目錄,官方文檔上是放到了drawable中了,大家可以根據(jù)喜好來放置,放在這兩個目錄都是可以運行的。
然后介紹一下布局文件res/layout/frame.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <ImageView android:id="@+id/frame_image" android:layout_width="fill_parent" android:layout_height="fill_parent" android:layout_weight="1"/> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="stopFrame" android:onClick="stopFrame"/> <Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="runFrame" android:onClick="runFrame"/> </LinearLayout>
我們定義了一個ImageView作為動畫的載體,然后定義了兩個按鈕,分別是停止和啟動動畫。
接下來介紹一下如何通過加載動畫定義文件來實現(xiàn)動畫的效果。我們首先會這樣寫:
package com.scott.anim; import android.app.Activity; import android.graphics.drawable.AnimationDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.view.View; import android.widget.ImageView; public class FrameActivity extends Activity { private ImageView image; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.frame); image = (ImageView) findViewById(R.id.frame_image); image.setBackgroundResource(R.anim.frame); AnimationDrawable anim = (AnimationDrawable) image.getBackground(); anim.start(); } }
看似十分完美,跟官方文檔上寫的一樣,然而當我們運行這個程序時會發(fā)現(xiàn),它只停留在第一幀,并沒有出現(xiàn)我們期望的動畫,也許你會失望的說一句:“Why?”,然后你把相應(yīng)的代碼放在一個按鈕的點擊事件中,動畫就順利執(zhí)行了,再移回到onCreate中,還是沒效果,這個時候估計你會氣急敗壞的吼一句:“What the fuck!”。但是,什么原因呢?如何解決呢?
出現(xiàn)這種現(xiàn)象是因為當我們在onCreate中調(diào)用AnimationDrawable的start方法時,窗口Window對象還沒有完全初始化,AnimationDrawable不能完全追加到窗口Window對象中,那么該怎么辦呢?我們需要把這段代碼放在onWindowFocusChanged方法中,當Activity展示給用戶時,onWindowFocusChanged方法就會被調(diào)用,我們正是在這個時候?qū)崿F(xiàn)我們的動畫效果。當然,onWindowFocusChanged是在onCreate之后被調(diào)用的,如圖:
然后我們需要重寫一下代碼:
package com.scott.anim; import android.app.Activity; import android.graphics.drawable.AnimationDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.view.View; import android.widget.ImageView; public class FrameActivity extends Activity { private ImageView image; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.frame); image = (ImageView) findViewById(R.id.frame_image); } @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); image.setBackgroundResource(R.anim.frame); AnimationDrawable anim = (AnimationDrawable) image.getBackground(); anim.start(); } }
運行一下,動畫就可以正常顯示了。
如果在有些場合,我們需要用純代碼方式實現(xiàn)一個動畫,我們可以這樣寫:
AnimationDrawable anim = new AnimationDrawable(); for (int i = 1; i <= 4; i++) { int id = getResources().getIdentifier("f" + i, "drawable", getPackageName()); Drawable drawable = getResources().getDrawable(id); anim.addFrame(drawable, 300); } anim.setOneShot(false); image.setBackgroundDrawable(anim); anim.start();
完整的FrameActivity.java代碼如下:
package com.scott.anim; import android.app.Activity; import android.graphics.drawable.AnimationDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.view.View; import android.widget.ImageView; public class FrameActivity extends Activity { private ImageView image; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.frame); image = (ImageView) findViewById(R.id.frame_image); } @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); image.setBackgroundResource(R.anim.frame); //將動畫資源文件設(shè)置為ImageView的背景 AnimationDrawable anim = (AnimationDrawable) image.getBackground(); //獲取ImageView背景,此時已被編譯成AnimationDrawable anim.start(); //開始動畫 } public void stopFrame(View view) { AnimationDrawable anim = (AnimationDrawable) image.getBackground(); if (anim.isRunning()) { //如果正在運行,就停止 anim.stop(); } } public void runFrame(View view) { //完全編碼實現(xiàn)的動畫效果 AnimationDrawable anim = new AnimationDrawable(); for (int i = 1; i <= 4; i++) { //根據(jù)資源名稱和目錄獲取R.java中對應(yīng)的資源ID int id = getResources().getIdentifier("f" + i, "drawable", getPackageName()); //根據(jù)資源ID獲取到Drawable對象 Drawable drawable = getResources().getDrawable(id); //將此幀添加到AnimationDrawable中 anim.addFrame(drawable, 300); } anim.setOneShot(false); //設(shè)置為loop image.setBackgroundDrawable(anim); //將動畫設(shè)置為ImageView背景 anim.start(); //開始動畫 } }
希望本文所述對大家Android程序設(shè)計有所幫助。
相關(guān)文章
Android設(shè)備與外接U盤實現(xiàn)數(shù)據(jù)讀取操作的示例
本篇文章主要介紹了Android設(shè)備與外接U盤實現(xiàn)數(shù)據(jù)讀取操作的示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-11-11Android RecyclerView上拉加載和下拉刷新(基礎(chǔ)版)
這篇文章主要為大家詳細介紹了Android RecyclerView上拉加載和下拉刷新的相實現(xiàn)方法,內(nèi)容簡單,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-02-02android基于socket的局域網(wǎng)內(nèi)服務(wù)器與客戶端加密通信
本篇文章主要介紹了android基于socket的局域網(wǎng)內(nèi)服務(wù)器與客戶端加密通信,這里整理了詳細的代碼,有需要的小伙伴可以參考下。2017-04-04