Android 屬性動畫Property Animation(上)介紹了屬性動畫的概念以及相關的類和介面,本篇來看下具體腫麼使用。
- ValueAnimator ValueAnimator指定整形、浮點型或者顏色值作為動畫值,在一定時間內平滑過渡。可以通過ofInt(),ofFloat(),或ofObject()來或得一個ValueAnimator,如:
ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f);
animation.setDuration(1000);
animation.start();
複製程式碼
當呼叫start()方法後,將一個浮點型值從0.0平滑過渡到1.0,時長1000毫秒。當然也可以自定義型別,如:
ValueAnimator animation = ValueAnimator.ofObject(new MyTypeEvaluator(), startPropertyValue, endPropertyValue);
animation.setDuration(1000);
animation.start();
複製程式碼
上述程式碼沒有實際效果,因為ValueAnimator並不直接作用於物件或屬性,通常會通過這些計算的值來不斷改變動畫的物件,可以通過設定監聽器並呼叫getAnimatedValue()來不斷獲得幀重新整理的計算值。如:
ValueAnimator animator = ValueAnimator.ofFloat(0f, 1f);
animator.setDuration(200);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = (float) animation.getAnimatedValue();
Log.e("TTT", "value is " + value);
}
});
animator.start();
複製程式碼
Log輸出:
E/TTT: value is 0.0
E/TTT: value is 0.0
E/TTT: value is 0.15204361
E/TTT: value is 0.36806342
E/TTT: value is 0.5
E/TTT: value is 0.63193655
E/TTT: value is 0.7545208
E/TTT: value is 0.85906315
E/TTT: value is 0.93815327
E/TTT: value is 0.98618495
E/TTT: value is 1.0
複製程式碼
上面程式碼是從0.0過渡到1.0,ofFloat()方法中可以傳入任意多個引數,如:ValueAnimator.ofFloat(0.0f, 0.5f, 0.75f, 1.0f)可以從0.0f過渡到0.5f,再過渡到0.75f,再過渡到1.0f。 ValueAnimator通常還有下面的方法:
//設定重複次數
animator.setRepeatCount(1);
//REVERSE 倒序播放 RESTART 重新播放
animator.setRepeatMode(ValueAnimator.REVERSE);
//延遲播放
animator.setStartDelay(1000);
//設定時間插值器為先加速後減速
animator.setInterpolator(new DecelerateInterpolator());
複製程式碼
ValueAnimator 還可以用XML檔案來寫,這樣寫的好處是更容易被複用,為了和API 11之前的動畫做區分,請將屬性動畫的XML檔案放在**res/animator/**目錄下,如新建一個value_animator.xml檔案,示例:
<?xml version="1.0" encoding="utf-8"?>
<animator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:repeatCount="1"
android:repeatMode="reverse"
android:valueFrom="0.0"
android:valueTo="1.0"
android:valueType="floatType" />
複製程式碼
在程式碼中載入XML檔案:
//載入XML檔案
ValueAnimator animator = (ValueAnimator) AnimatorInflater.loadAnimator(this, R.animator.value_animator);
//設定要執行動畫的目標
animator.setTarget(myObject);
//動畫執行
animator.start();
複製程式碼
還可以使用 PropertyValuesHolder和 Keyframe標籤建立一個多步的動畫,如:
<animator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:repeatCount="1"
android:repeatMode="reverse">
<propertyValuesHolder>
<keyframe android:fraction="0f" android:value="0f"/>
<keyframe android:fraction="0.5f" android:value="5f"/>
<keyframe android:fraction="1f" android:value="0f"/>
</propertyValuesHolder>
</animator>
複製程式碼
解釋一下PropertyValuesHolder和Keyframe: PropertyValuesHolder:顧名思義,就是屬性值持有者,它儲存了動畫過程中所需要操作的屬性和對應的值,我們通過ofFloat(Object target, String propertyName, float… values)構造的動畫,ofFloat()的內部實現其實就是將傳進來的引數封裝成PropertyValuesHolder例項來儲存動畫狀態。在封裝成PropertyValuesHolder例項以後,後面的操作也是以PropertyValuesHolder為主的。 **Keyframe:意為關鍵幀,設定了關鍵幀後,動畫就可以在各個關鍵幀之間平滑過渡的,一個關鍵幀必須包含兩個原素,第一時間點,第二位置,即這個關鍵幀是表示的是某個物體在哪個時間點應該在哪個位置上。fraction表示當前進度,value表示當前位置。 **如上面所示: 表示動畫進度為0時,動畫所在的數值位置為0; 表示動畫進度為50%時,動畫所在的數值位置為5; 表示動畫完成時,動畫所在的數值位置為0。
上述XML程式碼也可以用程式碼表示:
//建立關鍵幀
Keyframe keyframe1 = Keyframe.ofFloat(0f, 0f);
Keyframe keyframe2 = Keyframe.ofFloat(0.5f, 5f);
Keyframe keyframe3 = Keyframe.ofFloat(1.0f, 0f);
//建立PropertyValuesHolder
PropertyValuesHolder propertyValuesHolder = PropertyValuesHolder.ofKeyframe(propertyName, keyframe1, keyframe2, keyframe3);
//建立ObjectAnimator
ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(target, propertyValuesHolder);
//設定動畫時長
objectAnimator.setDuration(1000);
//設定動畫重複次數
objectAnimator.setRepeatCount(1);
//設定動畫重複模式
objectAnimator.setRepeatMode(ValueAnimator.REVERSE);
//啟動動畫
objectAnimator.start();
複製程式碼
如果想無限迴圈動畫,呼叫setRepeatCount(ValueAnimator.INFINITE)即可。
- AnimatorSet 如果想使用組合動畫,可以使用AnimatorSet將多個動畫組合到一起:
AnimatorSet bouncer = new AnimatorSet();
bouncer.play(bounceAnim).before(squashAnim1);
bouncer.play(squashAnim1).with(squashAnim2);
bouncer.play(squashAnim1).with(stretchAnim1);
bouncer.play(squashAnim1).with(stretchAnim2);
bouncer.play(bounceBackAnim).after(stretchAnim2);
ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
fadeAnim.setDuration(250);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.play(bouncer).before(fadeAnim);
animatorSet.start();
複製程式碼
執行順序: 1.執行bounceAnim動畫 2.同時執行squashAnim1, squashAnim2, stretchAnim1, stretchAnim2動畫 3.執行bounceBackAnim動畫 4.最後fadeAnim.