歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

基於OPhone 2.0的2D動畫實踐(一)

本系列文章主要介紹了OPhone 2.0 SDK提供的兩種實現2D動畫的方式:幀動畫和補間動畫。文章的每個知識點都提供了精彩的實例以向讀者展示2D動畫的具體實現方法。通過對本系列文章的學習,讀者可利用2D動畫實現非常絢麗的界面效果。

相關閱讀:

基於OPhone 2.0的2D動畫實踐(一) http://www.linuxidc.com/Linux/2011-11/48125.htm

基於OPhone 2.0的2D動畫實踐(二) http://www.linuxidc.com/Linux/2011-11/48124.htm

基於OPhone 2.0的2D動畫實踐(三) http://www.linuxidc.com/Linux/2011-11/48126.htm
 

  幀動畫簡介
  如果讀者使用過Flash,一定對幀動畫非常熟悉。幀動畫實際上就是由若干圖像組成的動畫。這些圖像會以一定的時間間隔進行切換。電影的原理也有些類似於幀動畫。一般電影是每秒25幀,也就是說,電影在每秒鐘內會以相等的時間間隔連續播放25幅電影靜態畫面。由於人的視覺暫留,在這樣的播放頻率下,看起來電影才是連續的。在onDraw方法中使用invalidate方法不斷刷新View的方式實現旋轉動畫。實際上,這也相當於幀動畫,只是並不是利用若干靜態圖像的不斷切換來制作幀動畫,而是不斷地畫出幀動畫中的每一幀圖像。


  AnimationDrawable與幀動畫
  OPhone中的幀動畫需要在一個動畫文件中指定動畫中的靜態圖像和每一張靜態圖像停留的時間(單位:毫秒)。一般可以將所有圖像的停留時間設為同一個值。動畫文件采用了XML格式。該文件需要放在res\anim目錄中。讓我們先來建立一個簡單的動畫文件,首先在res\anim目錄中建立一個test.xml文件,然後輸入如下的內容:

 
  1.   <animation-list xmlns:Android="http://schemas.android.com/apk/res/android" android:oneshot="false">   <item android:drawable="@drawable/anim1" android:duration="50" />   <item android:drawable="@drawable/anim2" android:duration="50" />   <item android:drawable="@drawable/anim3" android:duration="50" />   <item android:drawable="@drawable/anim4" android:duration="50" />   <item android:drawable="@drawable/anim5" android:duration="50" />   </animation-list>  
 

  從anim.xml文件的內容可以看出,一個標准的動畫文件由一個<animation-list>標簽和若干<item>標簽組成。其中<animation-list>標簽的一個關鍵屬性是android:oneshot,如果該屬性值為true,表示幀動畫只運行一遍,也就是從第1個圖像切換到最後一個圖像後,動畫就會停止。如果該屬性值為false,表示幀動畫循環播放。android:oneshot是可選屬性,默認值是false。
  <item>標簽的android:drawable屬性指定了動畫中的靜態圖像資源ID。幀動畫播放的順序就是<item>標簽的定義順序。android:duration屬性指定了每個圖像的停留時間。在test.xml文件中指定了每個圖像的停留時間為50毫秒。android:drawable和android:duration都是必選屬性,不能省略。
  編寫完動畫文件後,就需要裝載動畫文件,並創建AnimationDrawable對象。AnimationDrawable是Drawable的子類,並在Drawable的基礎上提供了控制動畫的功能。讀者可以使用如下的代碼來根據test.xml文件創建AnimationDrawable對象。

 
  1.   AnimationDrawable animationDrawable =   
  2.   (AnimationDrawable)getResources().getDrawable(R.anim.test);  
 
  在創建完AnimationDrawable對象後,可以使用下面的代碼將AnimationDrawable對象作為ImageView組件的背景。  
  1.   ImageView ivAnimView = (ImageView) findViewById(R.id.ivAnimView);   
  2.   ivAnimView.setBackgroundDrawable(animationDrawable);  
 
 除了可以使用getDrawable方法裝載test.anim文件外,還可以使用setBackgroundResource方法裝載test.xml文件,並通過getBackground方法獲得AnimationDrawable對象,代碼如下:  
  1.   ImageView ivAnimView = (ImageView) findViewById(R.id.ivAnimView);   
  2.   ivAnimView.setBackgroundResource(R.anim.test);   
  3.   Object backgroundObject = ivAnimView.getBackground();   
  4.   animationDrawable = (AnimationDrawable) backgroundObject;  
 
 有了AnimationDrawable對象,就可以通過AnimationDrawable類的方法來控制幀動畫。AnimationDrawable類中與幀動畫相關的方法如下:
   start:開始播放幀動畫。
   stop:停止播放幀動畫。
   setOneShot:設置是否只播放一遍幀動畫。該方法的參數值與動畫文件中的<animation-list>標簽的android:oneshot屬性值的含義相同。參數值為true表示只播放一遍幀動畫,參數值為false表示循環播放幀動畫。默認值為false。
   addFrame:向AnimationDrawable對象中添加新的幀。該方法有兩個參數,第1個參數是一個Drawable對象,表示添加的幀。該參數值可以是靜態圖像,也可以是另一個動畫。第2個參數表示新添加的幀的停留時間。如果新添加的幀是動畫。那麼這個停留時間就是新添加的動畫可以播放的時間。如果到了停留時間,不管新添加的動畫是否播放完,都會切換到下一個靜態圖像或動畫。
   isOneShot:判斷當前幀動畫是否只播放一遍。該方法返回通過setOneShot方法或android:oneshot屬性設置的值。
   isRunning:判斷當前幀動畫是否正在播放。如果返回true,表示幀動畫正在播放。返回false表示幀動畫已停止播放。
   getNumberOfFrames:返回動畫的幀數,也就是<animation-list>標簽中的<item>標簽數。
   getFrame:根據幀索引獲得指定的幀的Drawable對象。幀從0開始。
   getDuration:獲得指定幀的停留時間。
  如果想顯示半透明的幀動畫,可以通過Drawable類的setAlpha方法設置圖像的透明度,該方法只有一個int類型的值,該值的范圍是0至255。如果參數值是0,表示圖像完全透明,如果參數值是255,表示圖像完全不透明。

  通過幀動畫方式播放Gif動畫
  OPhone SDK中播放GIF動畫的類庫可能是因為GIF文件版本的問題,並不能播放所有的GIF動畫文件,但我們可以采用幀動畫的方式來播放GIF動畫。
  GIF動畫文件本身由多個靜態的GIF圖像組成,因此,可以使用圖像處理軟件(如FireWorks)將GIF動畫文件分解成多個GIF靜態圖像。然後將這些文件在res\anim目錄中的動畫文件中定義。frame_animation.xml文件的代碼如下:

 
  1.   <animation-list xmlns:android="http://schemas.android.com/apk/res/android"  
  2.    android:oneshot="false" >   
  3.    <item android:drawable="@drawable/anim1" android:duration="50" />   
  4.    <item android:drawable="@drawable/anim2" android:duration="50" />   
  5.   </animation-list>  
 
  為了演示在原有動畫的基礎上添加新的動畫,本例引入了第2個GIF動畫文件,並將這個GIF動畫文件分解成6個GIF靜態圖像(文件名從myanim1.gif至myanim6.gif)。定義這6個GIF文件的動畫文件是frame_animation1.xml。
  本例的功能包含了"開始動畫"、"停止動畫"、"運行一次動畫"和"添加動畫",這4個功能分別對應於4個按鈕。當單擊【開始動畫】按鈕後,動畫開始播放,如圖1所示。單擊【添加動畫】按鈕,播放完第1個動畫後,又會繼續播放第2個動畫,如圖2所示。在播放完第2個動畫後,又會繼續播放第1個動畫。

  圖1  播放第1個動畫

  圖2  播放第2個動畫


  本例的完整代碼如下:

  1.   package net.blogjava.mobile;   
  2.   
  3.   import android.app.Activity;   
  4.   import android.graphics.drawable.AnimationDrawable;   
  5.   import android.os.Bundle;   
  6.   import android.view.View;   
  7.   import android.view.View.OnClickListener;   
  8.   import android.widget.Button;   
  9.   import android.widget.ImageView;   
  10.   
  11.   public class Main extends Activity implements OnClickListener   
  12.   {   
  13.   private ImageView ivAnimView;   
  14.   private AnimationDrawable animationDrawable;   
  15.   private AnimationDrawable animationDrawable1;   
  16.   private Button btnAddFrame;   
  17.   @Override  
  18.   public void onClick(View view)   
  19.   {   
  20.   switch (view.getId())   
  21.   {   
  22.   //  只播放一次動畫   
  23.   case R.id.btnOneShot:             
  24.   animationDrawable.setOneShot(true);   
  25.   animationDrawable.start();   
  26.   break;   
  27.   //  循環播放動畫   
  28.   case R.id.btnStartAnim:   
  29.   animationDrawable.setOneShot(false);   
  30.   animationDrawable.stop();   
  31.   animationDrawable.start();   
  32.   break;   
  33.   //  停止播放動畫   
  34.   case R.id.btnStopAnim:   
  35.   animationDrawable.stop();   
  36.   if (animationDrawable1 != null)   
  37.   {   
  38.   //  停止新添加的動畫   
  39.   animationDrawable1.stop();   
  40.   }   
  41.   break;   
  42.   //  添加動畫   
  43.   case R.id.btnAddFrame:   
  44.   if (btnAddFrame.isEnabled())   
  45.   {   
  46.   //  獲得新添加動畫的AnimationDrawable對象   
  47.   animationDrawable1 = (AnimationDrawable) getResources()   
  48.   .getDrawable(R.anim.frame_animation1);   
  49.   //  添加動畫,動畫停留(播放)時間是2秒   
  50.   animationDrawable.addFrame(animationDrawable1, 2000);   
  51.   btnAddFrame.setEnabled(false);   
  52.   }   
  53.   break;   
  54.   }   
  55.   }   
  56.   @Override  
  57.   public void onCreate(Bundle savedInstanceState)   
  58.   {   
  59.   super.onCreate(savedInstanceState);   
  60.   setContentView(R.layout.main);   
  61.   Button btnStartAnim = (Button) findViewById(R.id.btnStartAnim);   
  62.   Button btnStopAnim = (Button) findViewById(R.id.btnStopAnim);   
  63.   Button btnOneShot = (Button) findViewById(R.id.btnOneShot);   
  64.   btnAddFrame = (Button) findViewById(R.id.btnAddFrame);   
  65.   btnStartAnim.setOnClickListener(this);   
  66.   btnStopAnim.setOnClickListener(this);   
  67.   btnOneShot.setOnClickListener(this);   
  68.   btnAddFrame.setOnClickListener(this);   
  69.   ivAnimView = (ImageView) findViewById(R.id.ivAnimView);   
  70.   ivAnimView.setBackgroundResource(R.anim.frame_animation);   
  71.   Object backgroundObject = ivAnimView.getBackground();   
  72.   animationDrawable = (AnimationDrawable) backgroundObject;           
  73.   }   
  74.   }  
 
  總結
  本文主要介紹了幀動畫的原理,並介紹了如何利用OPhone SDK中的API加載並運行幀動畫。最後給出了一個例子來用幀動畫的方式播放gif動畫。
Copyright © Linux教程網 All Rights Reserved