Android屬性動畫(一) 初識基本用法

1.介紹

Android系統爲我們提供了三種動畫效果的實現方式:

  • 補間動畫(Tween Animation):只能對View進行動畫操作,支持移動、旋轉、透明、縮放四種效果,有一定的侷限性。

  • 逐幀動畫(Frame Animation):把一個動畫分成多張圖片,然後把這些圖片連貫起來播放,原理和動畫片類似。

  • 屬性動畫(Property Animation):通過改變對象的屬性值來實現的動畫效果,不侷限使用在View上。

由於補間動畫的侷限性,Android團隊在3.0版本中引入了屬性動畫,它的功能相當強大,彌補了補間動畫的不足,幾乎可以完全替代補間動畫了。
如果你想在自定義控件的某一個點上使用動畫,給View設置一個平滑的顏色過渡,或者使用3D旋轉動畫,那麼屬性動畫一定是你最佳的選擇,下面就讓我們一起來看看屬性動畫的基本用法吧。

2.ValueAnimator

ValueAnimator是整個屬性動畫機制中最核心的一個類,因爲屬性動畫就是通過不斷的改變對象的屬性值來實現的動畫效果,初始值和結束值之間的動畫過渡就是由ValueAnimator這個類來完成計算的。
ValueAnimator的用法還是比較簡單的,比如想要把一個值從0平滑的過渡到1,間隔300ms,就可以這樣寫:

ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f);
animator.setDuration(300);
animator.start();

三行代碼搞定,是不是很簡單,但是這樣運行起來是看不出任何效果的,還需要加上一個監聽器:

ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f);
animator.setDuration(300);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        float currentValue = (float) animation.getAnimatedValue();
        Log.i("onAnimationUpdate", "currentValue:" + currentValue);
    }
});
animator.start();

運行一下,看下打印:

ValueAnimator

可以看到ValueAnimator幫我們計算了從0到1的過渡值,ofFloat方法是可以傳入多個參數的,比如在1s內,從0過渡到6,再過渡到3,然後再過渡到10,就可以這樣寫:

ValueAnimator animator = ValueAnimator.ofFloat(0f, 6f, 3f, 10f);
animator.setDuration(1000);
animator.start();

如果你不想要小數值過渡的話,還可以使用ofInt方法,使用和ofFloat方法相同,ValueAnimator中比較常用的就是ofFloat和oFInt方法了,還有一個ofObject,我會在下篇文章中講解。
可以看到上述代碼中,可以設置動畫的播放時間,除此之外還有一些常見的功能:

// 設置動畫的重複次數
// 直接傳入int型數值,INFINITE代表無限循環
animator.setRepeatCount(ValueAnimator.INFINITE);

// 設置動畫的重複模式
// RESTART代表重新播放,REVERSE代表倒序播放
animator.setRepeatMode(ValueAnimator.RESTART);
animator.setRepeatMode(ValueAnimator.REVERSE);

// 設置動畫的延遲播放時間
animator.setStartDelay(1000);

3.ObjectAnimator

與ValueAnimator相比ObjectAnimator纔是我們最常用到的類,ObjectAnimator繼承於ValueAnimator,其內部的動畫機制是依靠ValueAnimator來完成的,由於是繼承關係,在ObjectAnimator中也可以使用ValueAnimator中的一些方法,兩者的用法也很類似,下面就讓我們來看看ObjectAnimator的一些常見用法。

移動

把一張圖片沿X軸向右移動100px,然後向左移動回到原位:

// 沿X軸向移動100px,然後向左移動回到原位
// 沿Y軸移動,ofFloat第二個參數傳入translationY
ObjectAnimator animator = ObjectAnimator.ofFloat(image, "translationX", 0f, 100f, 0f);
// 動畫執行時長2s,默認300ms
animator.setDuration(2000);
animator.start();

移動

3D旋轉

把一張圖片垂直旋轉360度:

// 垂直旋轉360度
// 水平旋轉,ofFloat第二個參數傳入rotationX
ObjectAnimator animator = ObjectAnimator.ofFloat(image, "rotationY", 0f, 360f);
animator.setDuration(2000);
animator.start();

3D旋轉

透明

把一張圖片的透明度從0調節到1:

// 透明度從01
ObjectAnimator animator = ObjectAnimator.ofFloat(image, "alpha", 0f, 1f);
animator.setDuration(2000);
animator.start();

透明

縮放

把一張圖片水平縮放0.5倍,然後恢復:

// 水平縮放0.5倍,然後恢復
// 垂直縮放,ofFloat第二個參數傳入scaleY
ObjectAnimator animator = ObjectAnimator.ofFloat(image, "scaleX", 1f, 0.5f, 1f);
animator.setDuration(2000);
animator.start();

縮放

屬性動畫中圖片的移動是實現了圖片真正意義上的移動,改變位置後可以點擊,與此相比,補間動畫只是改變了圖片的顯示效果,移動後不能點擊,這也是屬性動畫和補間動畫的一個重要區別。
ofFloat方法的第二個參數可以傳入任意對象的屬性名,ObjectAnimator內部的工作原理就是通過在View中查找屬性名對應的get、set方法來設置對應的屬性值的。
通俗的來講,就是假如屬性名是alpha,ObjectAnimator就會在ImageView中查找getAlpha方法和setAlpha方法,然後進行透明度設置的。

4.組合動畫

組合動畫需要藉助AnimatorSet這個類來完成,AnimatorSet提供了play(Animator anim)方法,傳入Animator對象之後返回一個AnimatorSet.Builder實例,AnimatorSet.Builder中有下面幾個方法:

  • with(Animator anim):將現有的動畫和傳入的動畫同時執行。

  • before(Animator anim):將現有的動畫在傳入的動畫之前執行。

  • after(Animator anim):將現有的動畫在傳入的動畫之後執行。

  • after(long delay):將現有的動畫延時執行。

舉個栗子:

// 圖片從屏幕左側移動到右側,再回到原位,同時透明度從0調節到1,然後垂直旋轉360度
ObjectAnimator trans = ObjectAnimator.ofFloat(image, "translationX", -100f, 100f, 0f);
ObjectAnimator alpha = ObjectAnimator.ofFloat(image, "alpha", 0f, 1f);
ObjectAnimator rotation = ObjectAnimator.ofFloat(image, "rotationY", 0f, 360f);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.play(trans).with(alpha).before(rotation);
animatorSet.setDuration(5000);
animatorSet.start();

組合動畫

5.使用xml編寫動畫

在res目錄下創建一個animator文件夾,然後新建一個屬性動畫的xml文件,xml中可以使用如下三種標籤:

  • animator:對應代碼中的ValueAnimator類。

  • objectAnimator:對應代碼中的ObjectAnimator類。

  • set:對應代碼中的AnimatorSet類。

以上面的組合動畫爲例,使用xml來編寫下:

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:ordering="sequentially">

    <set android:ordering="together">
        <set android:ordering="sequentially">
            <objectAnimator
                android:duration="2000"
                android:propertyName="translationX"
                android:valueFrom="-100"
                android:valueTo="100"
                android:valueType="floatType" />

            <objectAnimator
                android:duration="2000"
                android:propertyName="translationX"
                android:valueFrom="100"
                android:valueTo="0"
                android:valueType="floatType" />
        </set>

        <objectAnimator
            android:duration="2000"
            android:propertyName="alpha"
            android:valueFrom="0"
            android:valueTo="1"
            android:valueType="floatType" />
    </set>

    <objectAnimator
        android:duration="2000"
        android:propertyName="rotationY"
        android:valueFrom="0"
        android:valueTo="360"
        android:valueType="floatType" />

</set>

ordering屬性可以設置爲sequentially(順序執行)、together(同時執行)。
在代碼中調用:

// 圖片從屏幕左側移動到右側,再回到原位,同時透明度從0調節到1,然後垂直旋轉360度
Animator animator = AnimatorInflater.loadAnimator(this, R.animator.combine);
animator.setTarget(image);
animator.start();

6.寫在最後

Ok,到這裏屬性動畫的基本用法就講完了,在下篇文章中我會寫一些屬性動畫的高級用法,敬請期待!

源碼已託管到GitHub上,歡迎Fork,覺得還不錯就Start一下吧!

GitHub地址:https://github.com/alidili/PropertyAnimationDemo

歡迎同學們吐槽評論,如果你覺得本篇博客對你有用,那麼就留個言或者頂一下吧(^-^)

《Android屬性動畫(二) ValueAnimator的實際應用 & 自定義TypeEvaluator》

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