編輯:關於Android編程
本文實例分析了Android動畫之逐幀動畫。分享給大家供大家參考,具體如下:
在開始實例講解之前,先引用官方文檔中的一段話:
Frame動畫是一系列圖片按照一定的順序展示的過程,和放電影的機制很相似,我們稱為逐幀動畫。Frame動畫可以被定義在XML文件中,也可以完全編碼實現。
如果被定義在XML文件中,我們可以放置在/res下的anim或drawable目錄中(/res/[anim | drawable]/filename.xml),文件名可以作為資源ID在代碼中引用;如果由完全由編碼實現,我們需要使用到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的話,此動畫只會執行一次,如果為false則一直循環。
<item>元素代表一幀動畫,android:drawable指定此幀動畫所對應的圖片資源,android:druation代表此幀持續的時間,整數,單位為毫秒。
文檔接下來的示例我就不在解說了,因為接下來我們也要結合自己的實例演示一下這個過程。
我們新建一個名為anim的工程,將四張連續的圖片分別命名為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中了,大家可以根據喜好來放置,放在這兩個目錄都是可以運行的。
然後介紹一下布局文件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作為動畫的載體,然後定義了兩個按鈕,分別是停止和啟動動畫。
接下來介紹一下如何通過加載動畫定義文件來實現動畫的效果。我們首先會這樣寫:
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(); } }
看似十分完美,跟官方文檔上寫的一樣,然而當我們運行這個程序時會發現,它只停留在第一幀,並沒有出現我們期望的動畫,也許你會失望的說一句:“Why?”,然後你把相應的代碼放在一個按鈕的點擊事件中,動畫就順利執行了,再移回到onCreate中,還是沒效果,這個時候估計你會氣急敗壞的吼一句:“What the fuck!”。但是,什麼原因呢?如何解決呢?
出現這種現象是因為當我們在onCreate中調用AnimationDrawable的start方法時,窗口Window對象還沒有完全初始化,AnimationDrawable不能完全追加到窗口Window對象中,那麼該怎麼辦呢?我們需要把這段代碼放在onWindowFocusChanged方法中,當Activity展示給用戶時,onWindowFocusChanged方法就會被調用,我們正是在這個時候實現我們的動畫效果。當然,onWindowFocusChanged是在onCreate之後被調用的,如圖:
然後我們需要重寫一下代碼:
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(); } }
運行一下,動畫就可以正常顯示了。
如果在有些場合,我們需要用純代碼方式實現一個動畫,我們可以這樣寫:
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); //將動畫資源文件設置為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) { //完全編碼實現的動畫效果 AnimationDrawable anim = new AnimationDrawable(); for (int i = 1; i <= 4; i++) { //根據資源名稱和目錄獲取R.java中對應的資源ID int id = getResources().getIdentifier("f" + i, "drawable", getPackageName()); //根據資源ID獲取到Drawable對象 Drawable drawable = getResources().getDrawable(id); //將此幀添加到AnimationDrawable中 anim.addFrame(drawable, 300); } anim.setOneShot(false); //設置為loop image.setBackgroundDrawable(anim); //將動畫設置為ImageView背景 anim.start(); //開始動畫 } }
希望本文所述對大家Android程序設計有所幫助。
在Android中,可以有多種方式來實現網絡編程:創建URL,並使用URLConnection/HttpURLConnection使用HttpClient使用WebVie
Android基礎入門教程——9.4 使用MediaRecord錄音標簽(空格分隔): Android基礎入門教程本節引言 本節是Android多
Android Activity學習筆記——Activity的啟動和創建 最近學習Android相關知識,感覺僅僅了解Activity幾個生命周期函數基本上沒有任
前一遍文章我們講了靜態創建Fragment,這個在實際的開發中幾乎不用,都是動態創建的,所謂動態創建就是根據某個條件動態創建Fragment, 現在創建一個android