本系列文章主要介紹了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
旋轉補間動畫
通過<rotate>標簽可以定義旋轉補間動畫。下面的代碼定義了一個標准的旋轉補間動畫。
- <rotate xmlns:Android="http://schemas.android.com/apk/res/android" android:interpolator="@anim/linear_interpolator" android:fromDegrees="0" android:toDegrees="360" android:pivotX="50%" android:pivotY="50%" android:duration="10000" android:repeatMode="restart" android:repeatCount="infinite"/>
其中<rotate>標簽有兩個特殊的屬性。它們的含義如下:
android:fromDegrees:表示旋轉的起始角度。
android:toDegrees:表示旋轉的結束角度。
在<rotate>標簽中還使用如下兩個屬性設置旋轉的次數和模式。
android:repeatCount:設置旋轉的次數。該屬性需要設置一個整數值。如果該值為0,表示不重復顯示動畫。也就是說,對於上面的旋轉補間動畫,只從0度旋轉到360度,動畫就會停止。如果屬性值大於0,動畫會再次顯示該屬性指定的次數。例如,如果android:repeatCount屬性值為1。動畫除了正常顯示一次外,還會再顯示一次。也就是說,前面的旋轉補間動畫會順時針自轉兩周。如果想讓補間動畫永不停止,可以將android:repeatCount屬性值設為"infinite"或-1。該屬性的默認值是0。
android:repeatMode:設置重復的模式。默認值是restart。該屬性只有當android:repeatCount設置成大於0的數或infinite才起作用。android:repeatMode屬性值除了可以是restart外,還可以設為reverse,表示偶數次顯示動畫時會做與動畫文件定義的方向相反的動作。例如,上面定義的旋轉補間動畫會在第1、3、5、...、2n - 1圈順時針旋轉,而在2、4、6、...、2n圈逆時針旋轉。如果想使用Java代碼來設置該屬性,可以使用Animation類的setRepeatMode方法。該方法只接收一個int類型參數。可取的值是Animation.RESTART和Animation.REVERSE。
如果想通過Java代碼實現旋轉補間動畫,可以創建android.view.animation.RotateAnimation對象。RotateAnimation類構造方法的定義如下:
- public RotateAnimation(float fromDegrees, float toDegrees, float pivotX, float pivotY);
通過RotateAnimation類的構造方法可以設置旋轉開始角度(fromDegrees)、旋轉結束角度(toDegrees)、旋轉支點橫坐標(pivotX)和旋轉支點縱坐標(pivotY)。
旋轉補間動畫實例
本例實現了兩顆行星繞著一顆恆星旋轉的效果。其中恆星會順時針和逆時針交替旋轉(android:repeatMode屬性值為reverse)。效果如圖1所示。
圖1 旋轉的星系
兩顆行星和一顆恆星分別對應於一個動畫文件。行星對應的兩個動畫文件的內容如下:
- hesper.xml
- <rotate xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@anim/linear_interpolator" android:fromDegrees="0"
- android:toDegrees="360" android:pivotX="200%" android:pivotY="300%"
- android:duration="5000" android:repeatMode="restart" android:repeatCount="infinite"/>
- earth.xml
- <rotate xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@anim/linear_interpolator" android:fromDegrees="0"
- android:toDegrees="360" android:pivotX="200%" android:pivotY="300%"
- android:duration="10000" android:repeatMode="restart" android:repeatCount="infinite"/>
恆星對應的動畫文件的內容如下:
- sun.xml
- <rotate xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@anim/linear_interpolator" android:fromDegrees="0"
- android:toDegrees="360" android:pivotX="50%" android:pivotY="50%"
- android:duration="20000" android:repeatMode="reverse" android:repeatCount="infinite"/>
本例的主程序相對簡單,只需要裝載這3個動畫文件,並開始動畫即可,代碼如下:
- package net.blogjava.mobile;
-
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.animation.Animation;
- import android.view.animation.AnimationUtils;
- import android.widget.ImageView;
-
- public class Main extends Activity
- {
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- ImageView ivEarth = (ImageView) findViewById(R.id.ivEarth);
- ImageView ivHesper = (ImageView) findViewById(R.id.ivHesper);
- ImageView ivSun = (ImageView) findViewById(R.id.ivSun);
- Animation earthAnimation = AnimationUtils.loadAnimation(this,R.anim.earth);
- Animation hesperAnimation = AnimationUtils.loadAnimation(this,R.anim.hesper);
- Animation sunAnimation = AnimationUtils.loadAnimation(this, R.anim.sun);
- ivEarth.startAnimation(earthAnimation);
- ivHesper.startAnimation(hesperAnimation);
- ivSun.startAnimation(sunAnimation);
- }
- }
透明度補間動畫
通過<alpha>標簽可以定義透明度補間動畫。下面的代碼定義了一個標准的透明度補間動畫。
- <alpha xmlns:android="http://schemas.android.com/apk/res/android"
- android:interpolator="@android:anim/accelerate_interpolator"
- android:fromAlpha="1.0" android:toAlpha="0.1" android:duration="2000" />
其中android:fromAlpha和android:toAlpha屬性分別表示起始透明度和結束透明度。這兩個屬性的值都在0.0和1.0之間。屬性值為0.0表示完全透明,屬性值為1.0表示完全不透明。
如果想通過Java代碼實現透明度補間動畫,可以創建android.view.animation.AlphaAnimation對象。AlphaAnimation類構造方法的定義如下:
- public AlphaAnimation(float fromAlpha, float toAlpha);
通過AlphaAnimation類的構造方法可以設置起始透明度(fromAlpha)和結束透明度(toAlpha)
透明度補間動畫實例
本例將前面介紹的多種動畫效果進行結合實現了投擲炸彈,並爆炸的特效。在本例中采用的動畫類型有幀動畫、移動補間動畫、縮放補間動畫和透明度補間動畫。
其中使用了幀動畫播放了一個爆炸的GIF動畫;使用移動補間動畫實現了炸彈被投下仍然會向前移動的偏移效果;縮放補間動畫實現了當炸彈被投下時逐漸縮小的效果。透明度補間動畫實現了炸彈被投下時逐漸模糊的效果。當運行本例後,會在屏幕下方正中間顯示一個炸彈,如圖2所示。然後觸摸這個炸彈,炸彈開始投擲,逐漸變小和模糊,如圖3所示。當炸彈變得很小、很模糊時,會播放GIF動畫來顯示爆炸效果,並播放爆炸的聲音。如圖4所示。
圖2 初始狀態的炸彈
圖3 炸彈逐漸變小和模糊
圖4 炸彈爆炸的效果
本例的實現代碼如下:
- package net.blogjava.mobile;
-
- import android.app.Activity;
- import android.graphics.drawable.AnimationDrawable;
- import android.media.MediaPlayer;
- import android.os.Bundle;
- import android.view.MotionEvent;
- import android.view.View;
- import android.view.View.OnTouchListener;
- import android.view.animation.Animation;
- import android.view.animation.AnimationUtils;
- import android.view.animation.Animation.AnimationListener;
- import android.widget.ImageView;
-
- public class Main extends Activity implements OnTouchListener,AnimationListener
- {
- private ImageView ivMissile;
- private MyImageView ivBlast;
- private AnimationDrawable animationDrawable;
- private Animation missileAnimation;
- @Override
- public boolean onTouch(View view, MotionEvent event)
- {
- // 觸摸炸彈後,開始播放動畫
- ivMissile.startAnimation(missileAnimation);
- return false;
- }
- @Override
- public void onAnimationEnd(Animation animation)
- {
- // 在播放投擲炸彈動畫結束後,顯示MyImageView組件,並將顯示炸彈的ImageView組件隱藏
- ivBlast.setVisibility(View.VISIBLE);
- ivMissile.setVisibility(View.INVISIBLE);
- try
- {
- // ���始播放爆炸的聲音
- MediaPlayer mediaPlayer = MediaPlayer.create(this, R.raw.bomb);
- mediaPlayer.stop();
- mediaPlayer.prepare();
- mediaPlayer.start();
- }
- catch (Exception e)
- {
- }
- animationDrawable.stop();
- // 播放爆炸效果動畫
- animationDrawable.start();
- }
- @Override
- public void onAnimationRepeat(Animation animation)
- {
- }
- @Override
- public void onAnimationStart(Animation animation)
- {
- }
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- ivMissile = (ImageView) findViewById(R.id.ivMissile);
- ivMissile.setOnTouchListener(this);
- ivBlast = (MyImageView) findViewById(R.id.ivBlast);
- ivBlast.setBackgroundResource(R.anim.blast);
- Object backgroundObject = ivBlast.getBackground();
- animationDrawable = (AnimationDrawable) backgroundObject;
- ivBlast.animationDrawable = animationDrawable;
- missileAnimation = AnimationUtils.loadAnimation(this, R.anim.missile);
- missileAnimation.setAnimationListener(this);
- // 在程序啟動後,將顯示爆炸效果的MyImageView組件隱藏
- ivBlast.setVisibility(View.INVISIBLE);
- ivBlast.ivMissile = ivMissile;
- }
- }
總結
本文主要介紹了旋轉補間動畫和透明度補間動畫。通過將四種補間動畫結合使用,可以實現非常有趣的動畫效果。