歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 基於OPhone 2.0的2D動畫實踐(二)

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

日期:2017/3/1 10:55:43   编辑:Linux編程

本系列文章主要介紹了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

  補間動畫簡介
  如果動畫中的圖像變換比較有規律時,可以采用自動生成中間圖像的方式來生成動畫。例如,圖像的移動、旋轉、縮放等。當然,還有更復雜的情況,例如,由正方形變成圓形、圓形變成橢圓形,這些變化過程中的圖像都可以根據一定的數學算法自動生成。而我們只需要指定動畫的第1幀和最後一幀的圖像即可。這種自動生成中間圖像的動畫被稱為補間(Tween)動畫。
  補間動畫的優點是節省硬盤空間。這是因為這種動畫只需要提供兩幀圖像(第1幀和最後一幀),其他的圖像都由系統自動生成。當然,這種動畫也有一定的缺點,就是動畫很復雜時無法自動生成中間圖像,例如,由電影畫面組件的動畫,由於每幅畫面過於復雜,系統無法預料下一幅畫面是什麼樣子。因此,這種復雜的動畫只能使用幀動畫來完成。在本節將介紹OPhone SDK提供的4種補間動畫效果:移動、縮放、旋轉和透明度。OPhone SDK並未提供更復雜的補間動畫。如果要實現更復雜的補間動畫,需要開發人員自已編碼來完成。

  移動補間動畫
  移動是最常見的動畫效果。我們可以通過配置動畫文件(xml文件)或Java代碼來實現補間動畫的移動效果。補間動畫文件需要放在res\anim目錄中。在動畫文件中通過<translate>標簽設置移動效果。假設在res\anim目錄下有一個動畫文件:test.xml,該文件的內容如下:

  1. <translate xmlns:Android="http://schemas.android.com/apk/res/android"
  2.   android:interpolator="@android:anim/accelerate_interpolator"
  3.   android:fromXDelta="0" android:toXDelta="320" android:fromYDelta="0"
  4.   android:toYDelta="0" android:duration="2000" />
 
  從上面的配置代碼可以看出,<translate>標簽中設置了6個屬性,這6個屬性的含義如下:
   android:interpolator:表示動畫渲染器。通過android:interpolator屬性可以設置3個動畫渲染器:accelerate_interpolator(動畫加速器)、decelerate_interpolator(動畫減速器)和accelerate_decelerate_interpolator(動畫加速減速器)。動畫加速器使動畫在開始時速度最慢,然後逐漸加速。動畫減速器使動畫在開始時速度最快,然後逐漸減速。動畫加速減速器使動畫在開始和結束時速度最慢,但在前半部分時開始加速,在後半部分時開始減速。
   android:fromXDelta:動畫起始位置的橫坐標。
   android:toXDelta:動畫結束位置的橫坐標。
   android:fromXDelta:動畫起始位置的縱坐標。
   android:toYDelta:動畫結束位置的縱坐標。
   android:duration:動畫的持續時間。單位是毫秒。也就是說,動畫要在android:duration屬性指定的時間內從起始點移動到結束點。


  裝載補間動畫文件需要使用android.view.animation.AnimationUtils. loadAnimation方法,該方法的定義如下:

  1. public static Animation loadAnimation(Context context, int id);
 

  其中id表示動畫文件的資源ID。裝載test.xml文件的代碼如下:

  1. Animation animation = AnimationUtils.loadAnimation(this, R.anim.test);

  假設有一個EditText組件(editText),將test.xml文件中設置的補間動畫應用到EditText組件上的方式有如下兩種:
  1. 使用EditText類的startAnimation方法,代碼如下:

  1. editText.startAnimation(animation);
 

  2. 使用Animation類的start方法,代碼如下:

  1. // 綁定補間動畫
  2.   editText.setAnimation(animation);
  3.   // 開始動畫
  4.   animation.start();
 


  使用上面兩種方式開始補間動畫都只顯示一次。如果想循環顯示動畫,需要使用如下的代碼將動畫設置成循環狀態。

  1. animation.setRepeatCount(Animation.INFINITE);
 


  上面兩行代碼在開始動畫之前和之後執行都沒有問題。

  移動補間動畫的實例
  本例的動畫效果是在屏幕上方的EditText組件從左到右循環勻速水平移動。EditText下方的小球上下移動。從上到下移動時加速。從下到上移動時減速。
  本例涉及到3個動畫渲染器:accelerate_interpolator、decelerate_interpolator和linear_interpolator。其中前兩個動畫渲染器可以直接作為android:interpolator屬性的值,而linear_interpolator雖然在系統中已定義,但由於不是public的,因此,需要自己定義linear_interpolator.xml文件。當然,也可以將系統的linear_interpolator.xml文件復制到Eclipse工程中的res\anim目錄下。
  在本例中定義了3個動畫文件,其中translate_right.xml被應用於EditText組件。translate_bottom.xml(從上到下移動,加速)和translate_top.xml(從下到上移動,減速)被應用於小球(ImageView組件)。這3個動畫文件的內容如下:

  1. translate_right.xml
  2.   <translate xmlns:android="http://schemas.android.com/apk/res/android"
  3.   android:interpolator="@anim/linear_interpolator"
  4.   android:fromXDelta="-320" android:toXDelta="320" android:fromYDelta="0"
  5.   android:toYDelta="0" android:duration="5000" />
  6. translate_bottom.xml
  7.   <translate xmlns:android="http://schemas.android.com/apk/res/android"
  8.    android:interpolator="@android:anim/accelerate_interpolator"
  9.    android:fromXDelta="0" android:toXDelta="0" android:fromYDelta="0"
  10.    android:toYDelta="260" android:duration="2000" />
  11. translate_top.xml
  12.   <translate xmlns:android="http://schemas.android.com/apk/res/android"
  13.   android:interpolator="@android:anim/decelerate_interpolator"
  14.   android:fromXDelta="0" android:toXDelta="0" android:fromYDelta="260"
  15.   android:toYDelta="0" android:duration="2000" />
 
  EditText組件的循環水平移動可以直接使用setRepeatMode和setRepeatCount方法進行設置。而小球的移動需要應用兩個動畫文件。本例采用的方法是在一個動畫播放完後,再將另一個動畫文件應用到顯示小球的ImageView組件中。這個操作需要在AnimationListener接口的onAnimationEnd方法中完成。
  運行本例後,單擊【開始動畫】按鈕後,EditText組件從屏幕的左側出來,循環水平向右移動,當EditText組件完全移進屏幕右側時,會再次從屏幕左側出來。同時小球會上下移動。效果如圖1所示。

  圖1 移動補間動畫

  本例的完整代碼如下:

  1. package net.blogjava.mobile;
  2.   import android.app.Activity;
  3.   import android.os.Bundle;
  4.   import android.view.View;
  5.   import android.view.View.OnClickListener;
  6.   import android.view.animation.Animation;
  7.   import android.view.animation.AnimationUtils;
  8.   import android.view.animation.Animation.AnimationListener;
  9.   import android.widget.Button;
  10.   import android.widget.EditText;
  11.   import android.widget.ImageView;
  12.   public class Main extends Activity implements OnClickListener, AnimationListener
  13.   {
  14.   private EditText editText;
  15.   private ImageView imageView;
  16.   private Animation animationRight;
  17.   private Animation animationBottom;
  18.   private Animation animationTop;
  19.   // animation參數表示當前應用到組件上的Animation對象
  20.   @Override
  21.   public void onAnimationEnd(Animation animation)
  22.   {
  23.   // 根據當前顯示的動畫決定下次顯示哪一個動畫
  24.   if (animation.hashCode() == animationBottom.hashCode())
  25.   imageView.startAnimation(animationTop);
  26.   else if (animation.hashCode() == animationTop.hashCode())
  27.   imageView.startAnimation(animationBottom);
  28.   }
  29.   @Override
  30.   public void onAnimationRepeat(Animation animation)
  31.   {
  32.   }
  33.   @Override
  34.   public void onAnimationStart(Animation animation)
  35.   {
  36.   }
  37.   @Override
  38.   public void onClick(View view)
  39.   {
  40.   // 開始EditText的動畫
  41.   editText.setAnimation(animationRight);
  42.   animationRight.start();
  43.   animationRight.setRepeatCount(Animation.INFINITE);
  44.   editText.setVisibility(EditText.VISIBLE);
  45.   // 開始小球的動畫
  46.   imageView.startAnimation(animationBottom);
  47.   }
  48.   @Override
  49.   public void onCreate(Bundle savedInstanceState)
  50.   {
  51.   super.onCreate(savedInstanceState);
  52.   setContentView(R.layout.main);
  53.   editText = (EditText) findViewById(R.id.edittext);
  54.   editText.setVisibility(EditText.INVISIBLE);
  55.   Button button = (Button) findViewById(R.id.button);
  56.   button.setOnClickListener(this);
  57.   imageView = (ImageView) findViewById(R.id.imageview);
  58.   animationRight = AnimationUtils.loadAnimation(this,R.anim.translate_right);
  59.   animationBottom = AnimationUtils.loadAnimation(this,R.anim.translate_bottom);
  60.   animationTop = AnimationUtils.loadAnimation(this, R.anim.translate_top);
  61.   animationBottom.setAnimationListener(this);
  62.   animationTop.setAnimationListener(this);
  63.   }
  64.   }
 
  縮放補間動畫
  通過<scale>標簽可以定義縮放補間動畫。下面的代碼定義了一個標准的縮��補間動畫。
  1. <scale xmlns:android="http://schemas.android.com/apk/res/android"
  2.   android:interpolator="@android:anim/decelerate_interpolator"
  3.   android:fromXScale="0.2" android:toXScale="1.0" android:fromYScale="0.2"
  4.   android:toYScale="1.0" android:pivotX="50%" android:pivotY="50%"
  5.   android:duration="2000" />
 
  <scale>標簽和<translate>標簽中有些屬性是相同的,而有些屬性是<scale>標簽特有的,這些屬性的含義如下:
   android:fromXScale:表示沿X軸縮放的起始比例。
   android:toXScale:表示沿X軸縮放的結束比例。
   android:fromYScale:表示沿Y軸縮放的起始比例。
   android:toYScale:表示沿Y軸縮放的結束比例。
   android:pivotX:表示沿X軸方向縮放的支點位置。如果該屬性值為"50%",則支點在沿X軸中心的位置。
   android:pivotY:表示沿Y軸方向縮放的支點位置。如果該屬性值為"50%",則支點在沿Y軸中心的位置。
  其中前4個屬性的取值規則如下:
   0.0:表示收縮到沒有。
   1.0:表示正常不收縮。
   大於1.0:表示將組件放大到相應的比例。例如,值為1.5,表示放大到原組件的1.5倍。
   小於1.0:表示將組件縮小到相應的比例。例如,值為0.5,表示縮小到原組件的50%。
  如果想通過Java代碼實現縮放補間動畫,可以創建android.view.animation.ScaleAnimation對象。ScaleAnimation類構造方法的定義如下:
  public ScaleAnimation(float fromX, float toX, float fromY, float toY,float pivotX, float pivotY)
  通過ScaleAnimation類的構造方法可以設置上述6個屬性值。設置其他屬性的方法與移動補間動畫相同。


  總結
  本文主要兩種補間動畫:移動補間動畫和縮放補間動畫,並給出了相應的實例。在下一篇文章中將會介紹另外兩種補間動畫。

Copyright © Linux教程網 All Rights Reserved