Android 屬性動畫Property Animation(中)

_小馬快跑_發表於2017-12-15

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.

下一篇:Android 屬性動畫Property Animation(下)

相關文章