視圖動畫相對於屬性動畫來說簡單一些,只能對view做移動、旋轉、縮放等處理。舉例來說做View移動的效果,視圖發生時改變View在屏幕上的繪製位置,但與這個View相關的屬性值卻不會改變,所以會發現響應點擊事件還在原來的位置上,也就是看上去變了,實際上根還在原來的地方;而屬性動畫改變的是實際的屬性值,也就是View位置發生變化了,他的相關屬性值也確實發生了改變。而且屬性動畫可以改變已有的屬性類型,還可以改變自定義的類型,也就是說屬性動畫是一種廣義的動畫系統,用於表現一種連續變化的過程,而不僅僅是視圖上的物理變化。
屬性動畫
屬性動畫主要涉及Animator、TimeInterpolator、TypeEvaluaor這三個概念。如果把屬性動畫看作一臺機器,那麼Animator就是其中的發動機。它定義了屬性動畫最基本的操作,ValueAnimator是它的子類,實現了動畫發生的具體計算過程。值得注意的是,ValueAnimator只負責動畫過程中屬性值得計算,具體得到這個變化的值如何處理ValueAnimator並不關心,所以需要使用者主動去獲取計算好的屬性值。ValueAnimator提供了三種默認支持的值類型,int、float和表示顏色的argb型。例如:
ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f);
animation.setDuration(1000);
animation.start();
要得到動畫發生過程中的值需要給ValueAnimator設置一個監聽器ValueAnimator.AnimatorUpdateListener。
animation.addUpdateListener(new AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator animator) {
Float value = (Float) animator.getAnimatedValue();
}
})
這樣就可以得到整個動畫過程產生的中間值。
中間值的計算涉及到兩個方面,一個是插值器函數,也就是對應的Interpolator,表示程度隨時間的變化情況,比如勻速、加速,或者先加速後減速等;另一個是中間值的計算函數,對應到TypeEvaluator,這是一個接口,裏面有evaluate(float fraction, T startValue, T endValue)方法需要實現,對一般的值計算方法都是startValue + fraction * (endValue - startValue),也有特殊的比如顏色值,用一個int表示了argb,計算的時候就要先分解計算再合成,但對於每個分量的計算任然遵守上面的規則,具體可以看ArgbEvaluator的源文件。
ValueAnimator除了上面的默認值類型,還支持自定義類型Object,對於自定義類型,使用者需要實現該類型對應的TypeEvaluator,如下
ValueAnimator animation = ValueAnimator.ofObject(new MyTypeEvaluator(), startPropertyValue, endPropertyValue);
animation.setDuration(1000);
animation.start();
屬性動畫要對View起作用需要將每次改變的屬性值設置到相應的View上,上面提到ValuAnimator只負責中間值的計算,而沒有後面這個值的設置過程,爲了更方便地運用,ObjectAnimator這個類誕生了,它繼承了ValueAnimator,並在內部實現了設置到View屬性上的邏輯。
ObjectAnimator anim = ObjectAnimator.ofFloat(foo, "alpha", 0f, 1f);
anim.setDuration(1000);
anim.start();
其中foo是屬性值所屬的一個具體對象,比如一個view,alpha是屬性名稱,ObjectAnimator要求必須有屬性名稱對應到set和get方法,如上面例子要求foo對應到類必須有setAlpha()和getAlpha()這兩個方法。對於View來說設置view的alpha值會觸發invalidate而重繪,因此就看到了連續的動畫效果。