Android中動畫:
- Tween Animation:通過對情境裡的對象不斷做映像變換(平移、縮放、旋轉)產生動畫效果,即是一種漸層動畫;
- Frame Animation:順序播放事先做好的映像,是一種畫面轉換動畫。
把這兩種動畫中的的各種用法整理了一下,具體代碼在附件中。如:
下面看下這兩種動畫的使用:
一 Tween Animation
Tween Animation有四種形式:
l alpha 漸層透明度動畫效果
l scale 漸層尺寸伸縮動畫效果
l translate 畫面位置移動動畫效果
l rotate 畫面旋轉動畫效果
這四種動畫實現方式都是通過Animation類和AnimationUtils配合實現。
可以通過xml實現:動畫的XML檔案在工程中res/anim目錄。
例如:rotate.xml
<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android" android:fillAfter = "false" android:zAdjustment="bottom" > <rotate android:fromDegrees="0" android:toDegrees="360" android:pivotX="50%" android:pivotY="50%" android:duration="4000" /></set>
實現動畫:
Animation anim = AnimationUtils.loadAnimation(mContext, R.anim.rotate);//監聽動畫的狀態(開始,結束)anim.setAnimationListener(new EffectAnimationListener());textWidget = (TextView)findViewById(R.id.text_widget);textWidget.setText(" 畫面轉移旋轉動畫效果");textWidget.startAnimation(anim);
具體使用方法就不用介紹了很簡單,每種形式的使用方法和效果可以見附件例子中。
二 Frame Animation
Frame Animation是順序播放事先做好的映像,跟電影類似。不同於animation package,
Android SDK提供了另外一個類AnimationDrawable來定義使用Frame Animation。
利用xml檔案實現:res/drawable-hdpi/frame.xml:
<?xml version="1.0" encoding="utf-8"?><animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="true" > <item android:drawable="@drawable/p1" android:duration="1000"></item> <item android:drawable="@drawable/p2" android:duration="1000"></item> <item android:drawable="@drawable/p3" android:duration="1000"></item> <item android:drawable="@drawable/p4" android:duration="1000"></item> <item android:drawable="@drawable/p5" android:duration="1000"></item> <item android:drawable="@drawable/p6" android:duration="1000"></item></animation-list>
實現動畫:
AnimationDrawable anim = (AnimationDrawable)getResources().getDrawable(R.drawable.frame);CustomAnimDrawable cusAnim = new CustomAnimDrawable(anim);cusAnim.setAnimationListener(new FrameAnimationListener());textWidget = (TextView)findViewById(R.id.text_widget);textWidget.setText(" 畫面逐幀動畫效果");textWidget.setBackgroundDrawable(anim);cusAnim.start();
這裡有點不同的是,利用AnimationDrawable實現動畫時,本身並沒有提供介面來監聽動畫的狀態(開始,結束),
這裡我自己簡單實現了一個方法來判斷動畫的狀態。CustomAnimDrawable是自己寫的繼承於AnimationDrawable的
一個類,用來根據播放第幾幀來判斷,避免了根據時間來判斷時,理論時間和實際時間不一致造成的影響。
用到了Java的反射機制。
CustomAnimDrawable實現:
public class CustomAnimDrawable extends AnimationDrawable { private final String TAG = "xmp"; private AnimationDrawable mOriAnim; private AnimationDrawable mSelf; private Handler mHandler; private boolean mStarted; private AnimEndListenerRunnable mEndRunnable; private AnimationDrawableListener mListener; public CustomAnimDrawable(AnimationDrawable anim) { mOriAnim = anim; initialize(); } private void initialize() { mSelf = this; mStarted = false; mHandler = new Handler(); mEndRunnable = new AnimEndListenerRunnable(); for (int i = 0; i < mOriAnim.getNumberOfFrames(); i++) { mSelf.addFrame(mOriAnim.getFrame(i), mOriAnim.getDuration(i)); } } @Override public void start() { mOriAnim.start(); mStarted = true; mHandler.post(mEndRunnable); if (mListener != null) { mListener.onAnimationStart(mSelf); } Log.v(TAG, "------CustomAnimDrawable------>start"); } /** * 迴圈檢測 動畫的狀態 */ class AnimEndListenerRunnable implements Runnable { @Override public void run() { // 動畫已開始 if (!mStarted) { return; } // 未停止繼續監聽 if (!isEnd()) {
//這裡的延遲時間是跟你的每一幀動畫時間有關,基本保持一致就可以,最後一幀也會完整播放
//上面動畫時間為每一幀1000ms,所以這裡設為了1000ms mHandler.postDelayed(mEndRunnable,1000); return; } Log.v(TAG, "----------->over"); // 動畫已結束 if (mListener != null) { mStarted = false; mListener.onAnimationEnd(mSelf); } } } /** * 判斷動畫是否結束 採用反射機制 * @return */ private boolean isEnd(){ Class<AnimationDrawable> animClass = AnimationDrawable.class; try{ //利用Java反射方法判斷是否結束 //獲得私人方法 例如 //Method method = animClass.getDeclaredMethod("nextFrame",boolean.class); //訪問其私人變數 Field field = animClass.getDeclaredField("mCurFrame"); field.setAccessible(true); int currFrameNum = field.getInt(mOriAnim); int totalFrameNum = mOriAnim.getNumberOfFrames(); if((currFrameNum == totalFrameNum - 1)|| (currFrameNum == -1)){ return true; } } catch (Exception e) { Log.v(TAG,"-------->Exception"); } return false; } public void setAnimationListener(AnimationDrawableListener listener) { mListener = listener; } public interface AnimationDrawableListener { /** * Notifies the start of the animation * @param animation */ public void onAnimationStart(AnimationDrawable animation); /** * Notifies the end of the animation * @param animation */ public void onAnimationEnd(AnimationDrawable animation); }}
廢話不說了,具體需要可以下載這個例子,包括基本的基礎動畫的使用。
代碼: http://files.cnblogs.com/bastard/animationTest.rar