Android 動畫——Frame Animation與Tween Animation

  很多手機應用的引導頁都是動畫的,添加動畫後的應用畫面會更加生動靈活,今天博主也學習了Android中Animation的使用,下面來總結下。
  Android中的Animation分爲兩種,一種是Frame Animation逐幀動畫,一種是Tween Animation補間動畫。

Frame Animation逐幀動畫

  逐幀動畫,顧名思義就是定義畫面播放的每一幀畫面,然後Android按照順序依次顯示。逐幀動畫與放電影的原理是相同的。下面我們來看逐幀動畫實現的具體步驟:
1. 首先在res文件下建立一個anim的文件夾,這個文件夾是專門用於存放Animation相關的xml文件的。
2. 在anim文件夾下創建一個animation_frame.xml的文件。該文件用於存放播放的每一幀畫面。

<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false">

    <item android:drawable="@mipmap/aa" android:duration="500"/>
    <item android:drawable="@mipmap/bb" android:duration="500"/>
    <item android:drawable="@mipmap/cc" android:duration="500"/>
    <item android:drawable="@mipmap/dd" android:duration="500"/>
    <item android:drawable="@mipmap/ee" android:duration="500"/>
    <item android:drawable="@mipmap/ff" android:duration="500"/>
    <item android:drawable="@mipmap/gg" android:duration="500"/>
    <item android:drawable="@mipmap/hh" android:duration="500"/>

</animation-list>

  <animation-list></animation-list>爲動畫的標籤,我們在這個標籤內通過定義<item/>項,來定義動畫顯示的每一個畫面。<animation-list > 標籤中android:oneshot="false" 這是一個非常重要的屬性,默認爲false 表示 動畫循環播放, 如果這裏寫true 則表示動畫只播發一次。<item/>標籤內的android:drawable用來定義畫面圖片,android:duration定義畫面的顯示時長。

3. 在Activity的xml佈局中定義兩個按鈕用於開始和停止播放控制,一個ImageView用於顯示動畫。在ImageView中通過設置設置背景引入我們剛纔寫的animation_frame.xml動畫文件。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.administrator.myanimation.FrameAnimationDemo">

    <Button
        android:id="@+id/button_play"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="開始播放" />

    <Button
        android:id="@+id/button_stop"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="停止播放" />

    <ImageView
        android:id="@+id/imageview_frame"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="@anim/animation_frame" />
</LinearLayout>

4. 在Activity中獲得佈局中相關控件的對象,並定義動畫,具體如下:

public class FrameAnimationDemo extends Activity implements View.OnClickListener {
    private Button mButtonPlay;//是定義停止按鈕
    private Button mButtonStop;//定義開始按鈕
    //定義顯示動畫的ImageView
    private ImageView mImageViewShow;
    //定義逐幀動畫
    private AnimationDrawable animationDrawable;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_frame_animation_demo);
        mButtonPlay = (Button) findViewById(R.id.button_play);//開始按鈕
        mButtonStop = (Button) findViewById(R.id.button_stop);//停止按鈕
        //獲得ImageView的對象
        mImageViewShow = (ImageView) findViewById(R.id.imageview_frame);
        //通過ImageView獲得逐幀動畫的對象
        animationDrawable = (AnimationDrawable) mImageViewShow.getBackground();
        //設置點擊事件
        mButtonPlay.setOnClickListener(this);
        mButtonStop.setOnClickListener(this);
    }
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.button_play:
                Log.d("data", "開始播放");
                animationDrawable.start();//開始播放
                break;
            case R.id.button_stop:
                Log.d("data", "開始播放");
                animationDrawable.stop();//停止播放
                break;
            default:
                break;
        }
    }
}

  逐幀動畫使用AnimationDrawanle,通過ImageView對象的getBackgroud()方法獲得AnimationDrawanle對象,然後調用start()方法開始播放動畫,調用stop()方法停止播放動畫。當然在逐幀動畫還可以通過addFrame(Drawable frame, int duration)方法添加每一幀的畫面,而不是定義animation_frame.xml文件。

AnimationDrawanle就是用來控制逐幀動畫的,他還提供了很多其他的方法進行操作(以下是常用的一部分):

start(); 開始這個動畫
stop(); 結束這個動畫
setAlpha(100);設置動畫的透明度, 取值範圍(0 - 255)
setOneShot(true); 設置單次播放
setOneShot(false); 設置循環播放
isRunning(); 判斷動畫是否正在播放
getNumberOfFrames(); 得到動畫的幀數。

這裏寫圖片描述

Tween Animation補間動畫

  補間動畫與逐幀動畫的區別是補間動畫不用自己去定義動畫的每一幀變化,我們只需要指定動畫的第一幀和最後一幀的關鍵幀即可,其中間的中間幀由系統自己去計算。
  Tween Animation動畫中可以定義動畫移動、放大、縮小以及產生透明度的變化,我們自己指定動畫的兩個關鍵幀以及動畫的變化方式,然後系統自己去計算動畫的中間變化和軌跡,也就是我們動畫的中間過程全是由系統幫我們完成的。這樣導致了一個缺點就是我們不容一區控制動畫的變化,所以在很多遊戲的開發中不會用到補間動畫。下面,我們來學習一下補間動畫的使用。
  補間動畫Tween Animation通過使用Animation來使用,我們首先來看一下Animation:
這裏寫圖片描述

Animation包含5個子類:
AlphaAnimation:透明度改變的動畫,通過指定動畫開始的透明度和結束的透明度,以及動畫 維持的時間。其中透明度是從0到1定義的。
RotateAnimation:旋轉的動畫,通過指定動畫開始時的旋轉角度和結束時的旋轉角度來定義動畫的旋轉。
ScaleAnimation:縮放的動畫,通過指定動畫X,Y軸的縮放,來對動畫進行縮放。
TranslateAnimation :平移的動畫,通過定義動畫在X, Y軸上的平移量來定義動畫的平移。
AnimationSet:混合的動畫,將以上動畫效果混合形成的動畫效果。

  下面我們分別來看5種動畫效果的實現,首先定義一個Activity的佈局文件,在佈局文件中定義5個按鈕分別實現 AlphaAnimation, AnimationSet, RotateAnimation, ScaleAnimation, TranslateAnimation 動畫,定義一個ImageView,顯示動畫效果。

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <LinearLayout
        android:id="@+id/layout1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center">

        <Button
            android:id="@+id/button_start_alpha"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:text="透明動畫" />
        <Button
            android:id="@+id/button_start_translate"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:text="平移動畫" />
        <Button
            android:id="@+id/button_start_rotate"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:text="旋轉動畫" />
        <Button
            android:id="@+id/button_start_scale"
            android:layout_width="0dp"
            android:layout_weight="1"
            android:layout_height="wrap_content"
            android:text="縮放動畫" />

    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/layout1">
        <Button
            android:id="@+id/button_start_set"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="混合動畫"/>
    </LinearLayout>


    <ImageView
        android:id="@+id/imageview"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:background="@mipmap/ic_launcher"
        android:layout_gravity="center"
        android:layout_centerInParent="true"/>

</RelativeLayout>

AlphaAnimation:

1. 創建一個AlphaAnimation的對象。AlphaAnimation有如下構造器:

  • AlphaAnimation(Context context, AttributeSet attrs)
      該構造器由於加載res文件夾anim文件夾中的xml配置時使用。
  • AlphaAnimation(float fromAlpha, float toAlpha)
      該構造器用於直接定義該動畫變化的透明度,從fromAlpha變化到toAlpha。範圍爲0到1。
      
      這裏我們使用第二個構造器。
    2. 設置AlphaAnimation對象動畫的顯示時間。通過調用setDuration(long durationMillis)方法。
    3. ImageView對象調用startAnimation(Animation animation)方法開始顯示動畫。
    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.button_start_alpha:
                mImageView.setImageResource(R.mipmap.ic_launcher);//設置畫面顯示
                //透明動畫
                AlphaAnimation animation = new AlphaAnimation(0.0f, 1.0f);
                animation.setDuration(5000);//動畫播放5秒
                mImageView.startAnimation(animation);
                break;
                default:
                break;
        }
    }

這裏寫圖片描述

TranslateAnimation:

  在平移動畫按鈕的點擊事件中定義如下:
1. 創建一個TranslateAnimation的對象。TranslateAnimation有如下構造器:

  • TranslateAnimation(Context context, AttributeSet attrs)
      該構造器由於加載res文件夾anim文件夾中的xml配置時使用。
  • TranslateAnimation(float fromXDelta, float toXDelta, float fromYDelta, float toYDelta)
      該構造器用於直接定義該動畫變化的位移,X軸從fromXDelta變化到toXDelta,Y軸從fromYDelta變化到toYDelta。
  • TranslateAnimation (int fromXType, float fromXValue, int toXType, float toXValue, int fromYType, float fromYValue, int toYType, float toYValue)
      該構造器也是用於直接定義該動畫變化的位移,fromXType是指後面fromXValue的數值是現對於自己的還是相對於父佈局的,它有兩個值:Animation.RELATIVE_TO_SELF, Animation.RELATIVE_TO_PARENT。後面的也是如此,座標的變化是:X軸從fromXValue變化到toXValue,Y軸從fromYValue變化到toYValue。

      這裏我們使用第二個構造器。
    2. 設置TranslateAnimation 對象動畫的顯示時間。通過調用setDuration(long durationMillis)方法。
    3. ImageView對象調用startAnimation(Animation animation)方法開始顯示動畫。

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.button_start_alpha:
                mImageView.setImageResource(R.mipmap.ic_launcher);//設置畫面顯示
                 TranslateAnimation animationTranslate = new TranslateAnimation(0, 2 * mImageView.getMeasuredWidth(), 0,
                        2 * mImageView.getMeasuredHeight());              
                animationTranslate.setDuration(5000);//動畫播放5秒
                mImageView.startAnimation(animationTranslate);
                break;
                default:
                break;
        }
    }

這裏寫圖片描述

RotateAnimation :

  在旋轉動畫按鈕的點擊事件中定義如下:
1. 創建一個RotateAnimation 的對象。RotateAnimation 有如下構造器:

  • RotateAnimation(Context context, AttributeSet attrs)
      該構造器由於加載res文件夾anim文件夾中的xml配置時使用。
  • RotateAnimation(float fromDegrees, float toDegrees)
      該構造器用於直接定義該動畫旋轉的角度,從fromDegrees變化到toDegrees。
  • RotateAnimation (float fromDegrees, float toDegrees, float pivotX, float pivotY)
      該構造器用於直接定義該動畫旋轉的角度和旋轉的中心,以(pivotX,pivotY)爲中心從fromDegrees變化到toDegrees。
  • RotateAnimation (float fromDegrees, float toDegrees, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)
      該構造器用於直接定義該動畫旋轉的角度和旋轉的中心,以(pivotXValue,pivotYValue)爲中心從fromDegrees變化到toDegrees。旋轉中心的定義有兩種類型:Animation.RELATIVE_TO_SELF, Animation.RELATIVE_TO_PARENT

      這裏我們使用第二個構造器。
    2. 設置RotateAnimation 對象動畫的顯示時間。通過調用setDuration(long durationMillis)方法。
    3. ImageView對象調用startAnimation(Animation animation)方法開始顯示動畫。

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.button_start_alpha:
                mImageView.setImageResource(R.mipmap.ic_launcher);//設置畫面顯示
                 //旋轉動畫
                RotateAnimation animationRoate = new RotateAnimation(0, 360);           
                animationTranslate.setDuration(5000);//動畫播放5秒
                mImageView.startAnimation(animationTranslate);
                break;
                default:
                break;
        }
    }

這裏寫圖片描述

ScaleAnimation:

  在縮放動畫按鈕的點擊事件中定義如下:
1. 創建一個ScaleAnimation的對象。ScaleAnimation有如下構造器:

  • ScaleAnimation(Context context, AttributeSet attrs)
      該構造器由於加載res文件夾anim文件夾中的xml配置時使用。
  • ScaleAnimation(float fromX, float toX, float fromY, float toY)
      該構造器用於直接定義該動畫縮放的大小,X軸從fromX變化到toX,Y軸從fromY變化到toY。
  • ScaleAnimation(float fromX, float toX, float fromY, float toY, float pivotX, float pivotY)
      該構造器用於直接定義該動動畫縮放的大小和縮放的中心,以(pivotX,pivotY)爲中心縮放。
  • ScaleAnimation(float fromX, float toX, float fromY, float toY, int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)
      該構造器用於直接定義該動動畫縮放的大小和縮放的中心,以(pivotX,pivotY)爲中心縮放。縮放中心的定義有兩種類型:Animation.RELATIVE_TO_SELF, Animation.RELATIVE_TO_PARENT

      這裏我們使用第二個構造器。
    2. 設置ScaleAnimation對象動畫的顯示時間。通過調用setDuration(long durationMillis)方法。
    3. ImageView對象調用startAnimation(Animation animation)方法開始顯示動畫。

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.button_start_alpha:
                mImageView.setImageResource(R.mipmap.ic_launcher);//設置畫面顯示
                //縮放動畫
                ScaleAnimation animationScale = new ScaleAnimation(0.0f, 1f, 0.0f, 1f);      
                animationTranslate.setDuration(5000);//動畫播放5秒
                mImageView.startAnimation(animationTranslate);
                break;
                default:
                break;
        }
    }

這裏寫圖片描述

AnimationSet:

  在混合動畫按鈕的點擊事件中定義如下:
1. 創建一個AnimationSet的對象。AnimationSet有如下構造器:

  • AnimationSet(Context context, AttributeSet attrs)
      該構造器由於加載res文件夾anim文件夾中的xml配置時使用。
  • AnimationSet (boolean shareInterpolator)
      是否共享Interpolator的設置。

      這裏我們使用第二個構造器。
    2. 設置AnimationSet對象動畫的顯示時間。通過調用setDuration(long durationMillis)方法。
    3. ImageView對象調用startAnimation(Animation animation)方法開始顯示動畫。

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.button_start_alpha:
                mImageView.setImageResource(R.mipmap.ic_launcher);//設置畫面顯示
                AnimationSet animationSet= new AnimationSet(false);

                //從透明到不透明
                AlphaAnimation animation1 = new AlphaAnimation(0.0f, 1.0f);
                //平移
                TranslateAnimation animation2 = new TranslateAnimation(0,mImageView.getMeasuredWidth(), 0,mImageView.getMeasuredHeight());
                //旋轉
                RotateAnimation animation3 = new RotateAnimation(0, 360);
                //縮放
                ScaleAnimation animation4 = new ScaleAnimation(0.0f, 1f, 0.0f, 1f);
                //爲混合動畫添加效果
                animationSet.addAnimation(animation1);
                animationSet.addAnimation(animation2);
                animationSet.addAnimation(animation3);
                animationSet.addAnimation(animation4);

                animationSet.setDuration(10000);//動畫播放10秒
                animationTranslate.setDuration(5000);//動畫播放5秒
                mImageView.startAnimation(animationTranslate);
                break;
                default:
                break;
        }
    }

這裏寫圖片描述

XML設置動畫:

  有時候我們會感覺在java代碼中設置代碼會使代碼看起來更加複雜和龐大,那麼爲了減少java代碼的附中,我們可以將對於動畫的設置提升成一個xml文件。這裏我們以縮旋轉爲例定義:
1. 首先在res文件夾下建立一個anim文件夾。
2. 在anim文件夾下創建一個animation_rotate.xml文件。
  這裏定義了動畫的時間,開始角度,結束角度,以及旋轉的中心和重複的次數。注意:repeatCount值爲:-1時,循環旋轉;0時, 旋轉一次;1時旋轉2次……以此類推。

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator">
    <rotate
        android:duration="3000"
        android:fromDegrees="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:repeatCount="1"
        android:toDegrees="360"></rotate>
</set>

3. 在Activity中加載animation_rotate.xml文件,AnimationUtils.loadAnimation()方法加載
  使用AnimationUtils.loadAnimation()方法加載返回一個Animation的對象。

//使用在AnimationUtils.loadAnimation()方法加載。
Animation animationRotate = AnimationUtils.loadAnimation(this, R.anim.animation_rotate);
mImageView.startAnimation(animationRotate);

這裏寫圖片描述

發佈了134 篇原創文章 · 獲贊 134 · 訪問量 38萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章