Property Animation
Property Animation是android3.0(API Level11)加入的新特性,能對任意對象的任意屬性進行動畫切換。Property Animation改變特定時間段內屬性的值。要實現動畫,需要指定對象動畫的特性,例如對象在屏幕上的位置,動畫持續的時長等。
Property Animation允許你定義的動畫的特性有:
l Duration:動畫的持續時間,默認值是300ms。
l TimeInterpolation:時間差值,定義隨着時間的變換,屬性值如何變換
l TypeEvaluator:根據屬性的開始、結束值與TimeInterpolation計算出的因子計算出當前時間的屬性值
l Repeat Country and behavoir:重複次數與方式,如播放3次、5次、無限循環,可以此動畫一直重複,或播放完時再反向播放
l Animation sets:動畫集合,即可以同時對一個對象應用幾個動畫,這些動畫可以同時播放也可以對不同動畫設置不同開始偏移
l Frame refreash delay:多少時間刷新一次,即每隔多少時間計算一次屬性值,默認爲10ms,最終刷新時間還受系統進程調度與硬件的影響
Property Animation相關類的繼承關係
java.lang.Object
android.animation.Animator
↳android.animation.ValueAnimator
↳android.animation.ObjectAnimator
ObjectAnimator
用ObjectAnimator可以方便快捷的實現動畫。使用時注意:
1、ObjectAnimator提供了ofInt、ofFloat、ofObject等幾個工廠方法,第一個參數爲對象名,第二個爲屬性名,後面的參數爲可變參數,如果values...參數只設置一個值的話,那麼會作爲目的值,屬性的變化範圍爲當前值到目的值。如果設置兩個,則一個爲開始值、一個爲結束值。
2、實際應用中會用ObjectAnimator改變某一對象的某一屬性,使用ObjectAnimator有限制,需要對象有一個setter函數和getter函數,就是set<PropertyName>和get<PropertyName>函數,用來更新某個屬性。
3、如果動畫的對象的屬性方法裏面,沒有調用view的重繪,則你需要自己按照下面方式手動調用。
anim.addUpdateListener(new AnimatorUpdateListener()
{
@Override
public voidonAnimationUpdate(ValueAnimator animation)
{
// view.postInvalidate();
// view.invalidate();
}
});
ValueAnimator
ValueAnimator有更大的靈活性,不需要操作的對象的屬性一定要有getter和setter方法,可以自己根據當前動畫的計算值來操作任何屬性。
ValueAnimator原理介紹
ValueAnimator對象持有動畫時間,比如動畫已經進行了多長時間,和變換的屬性的當前值。ValueAnimator中封裝了TimeInterpolator和TypeEvaluator。TimeInterpolator定義了動畫的時間插值,比如可以線性或者加速減速;TypeEvaluator定義瞭如何計算被動畫改變的屬性值。
爲了開啓一個動畫,首先構造一個ValueAnimator對象,把你想要改變的屬性值的起始值、終止值以及動畫時間告訴它,當你調用 start()方法時,動畫開始。
在整個動畫的過程中,所涉及的計算分爲下面三步:
1.這個ValueAnimator對象會根據動畫的總時間和已經流逝的時間計算出一個0到1之間的比值(fraction)。這個fraction值就代表了時間完成的程度。
2.計算出fraction之後,ValueAnimator對象會調用TimeInterpolator 來計算一個interpolatedfraction,即根據所設置的時間插值方法將elapsed fraction映射到interpolated fraction。
如果是線性插值的話elapsed fraction和interpolated fraction會是一直相等的,但是非線性變換就不是了。
3. interpolated fraction計算出來後,ValueAnimator 會調用TypeEvaluator,來進行你要動畫的屬性值的計算。
這時候用的輸入參數就是interpolated fraction的值,以及屬性值的起始值和終止值。
ValueAnimator包含Property Animation動畫的所有核心功能,如動畫時間,開始、結束屬性值,相應時間屬性值計算方法等。應用Property Animation有兩個步聚:
1、計算屬性值
2、根據屬性值執行相應的動作,如改變對象的某一屬性。
ValuAnimiator只完成了第一步工作,如果要完成第二步,需要實現ValueAnimator.onUpdateListener接口,這個接口只有一個函數onAnimationUpdate(),在這個函數中會傳入ValueAnimator對象做爲參數,通過這個ValueAnimator對象的getAnimatedValue()函數可以得到當前的屬性值如:
ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f);
animation.setDuration(1000);
animation.addUpdateListener(new AnimatorUpdateListener() {
@Override
publicvoid onAnimationUpdate(ValueAnimator animation) {
Log.i("update", ((Float)animation.getAnimatedValue()).toString());
}
});
animation.setInterpolator(new CycleInterpolator(3));
animation.start();
TypeEvalutor
根據屬性的開始、結束值與TimeInterpolation計算出的因子計算出當前時間的屬性值,android提供了以下幾個evalutor:
IntEvaluator:屬性的值類型爲int;
FloatEvaluator:屬性的值類型爲float;
ArgbEvaluator:屬性的值類型爲十六進制顏色值;
TypeEvaluator:一個接口,可以通過實現該接口自定義Evaluator。
根據動畫執行的時間跟應用的Interplator,會計算出一個0~1之間的因子,即evalute函數中的fraction參數。也就是在TypeEvaluator的evaluator方法中,我們可以自己定義一個規格告訴機器屬性怎麼變化。
下面是一個例子:
TypeEvaluator typeEvaluator = new TypeEvaluator() {
@Override
publicObject evaluate(float fraction, Object o, Object o2) {
PointF point = new PointF();
point.x = (float) (width / 2 + 200 * Math.cos(fraction * 2 *Math.PI));
point.y = (float) (height / 2 + 200 * Math.sin(fraction * 2 *Math.PI));
return point;
}
};
TimeInterplator
TimeInterplator定義了屬性值隨時間變化的方式,如線性均勻改變,開始慢然後逐漸快等。
系統提供的插補器有下面幾個:
1.AccelerateDecelerateInterpolator 加速減速插補器
2.DecelerateInterpolator 減速插補器
3.AnticipateInterpolator 向前插補器
4.AnticipateOvershootInterpolator 向前向後插補器
5.OvershootInterpolator 超出插補器
還有循環插補器CycleInterpolator 和反彈插補器BounceInterpolator,基本原理都一樣,只是函數圖象需要做更細的分段處理。
Animator.AnimatorListener
Animator.AnimatorLIstener中要實現onAnimationStart()、onAnimationEnd()、onAnimationRepeat()、onAnimationCancel()(當動畫被取消時調用,同時會調用onAnimationEnd())這幾個方法。
ValueAnimator.AnimatorUpdateListener
通過監聽這個事件在屬性的值更新時在onAnimationUpdate()方法中執行相應的操作,對於ValueAnimator一般要監聽此事件執行相應的動作,不然Animation沒意義,在ObjectAnimator(繼承自ValueAnimator)中會自動更新屬性,如無必要不必監聽。在函數中會傳遞一個ValueAnimator參數,通過此參數的getAnimatedValue()取得當前動畫屬性值。
可以繼承AnimatorListenerAdapter而不是實現AnimatorListener接口來簡化操作,這個類對AnimatorListener中的函數都定義了一個空函數體,這樣我們就只用定義想監聽的事件而不用實現每個函數卻只定義一空函數體。
AnimationSet
可以用AnimationSet實現多個動畫