Android中動畫學習


Android中動畫:

  1. Tween Animation:通過對場景里的對象不斷做圖像變換(平移、縮放、旋轉)產生動畫效果,即是一種漸變動畫;
  2. 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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM