動畫介紹:
- 在Android動畫中,總共有兩種類型的動畫View Animation(視圖動畫)和Property Animator(屬性動畫)背犯;
- View Animation包括Tween Animation(補間動畫)和Frame Animation(逐幀動畫)匀油;
Property Animator包括ValueAnimator和ObjectAnimation浴栽;
區(qū)別:
- View Animation僅能對指定的控件做動畫做盅,而Property Animator是通過改變控件某一屬性值來做動畫的最冰。
- 補間動畫雖能對控件做動畫匣缘,但并沒有改變控件內(nèi)部的屬性值猖闪。而Property Animator則是恰恰相反,Property Animator是通過改變控件內(nèi)部的屬性值來達到動畫效果的肌厨。
屬性動畫:
ValueAnimator
- 注意:單從名字上就可以看出來培慌,這個Animator是針對數(shù)值進行操作的,不對控件做操作柑爸〕郴ぃ控件和它并沒有什么關(guān)系,重點在數(shù)值上的操作表鳍。
- 兩點:
- ValueAnimator只負責(zé)對指定數(shù)值區(qū)間馅而,進行運算。
- 自己需要對運算進行監(jiān)聽譬圣,然后自己對控件進行操作瓮恭。
ValueAnimator animator = ValueAnimator.ofInt(0,400);
animator.setDuration(1000);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
//拿到監(jiān)聽結(jié)果,自己處理厘熟。
int curValue = (int)animation.getAnimatedValue();
tvTextView.layout(curValue,curValue,curValue+tv.getWidth(),curValue+tv.getHeight());
}
});
animator.start();
常用方法和監(jiān)聽:
- 方法:和Animation差不多屯蹦,看文檔。
- 監(jiān)聽:
- AnimatorUpdateListener:監(jiān)聽動畫變化時的實時值绳姨。addUpdateListener(AnimatorUpdateListener listener)登澜。
- AnimatorListener:監(jiān)聽動畫變化時四個狀態(tài)。addListener(AnimatorListener listener)飘庄。
- 移除監(jiān)聽:
/**
* 移除AnimatorUpdateListener
*/
void removeUpdateListener(AnimatorUpdateListener listener);
void removeAllUpdateListeners();
/**
* 移除AnimatorListener
*/
void removeListener(AnimatorListener listener);
void removeAllListeners();
查看這段代碼:
ValueAnimator animator = ValueAnimator.ofInt(0,600);
animator.setDuration(1000);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int curValue = (int)animation.getAnimatedValue();
}
});
animator.setInterpolator(new LinearInterpolator());
animator.start();
上面代碼中脑蠕,在1000毫秒的時間中,ValueAnimator的功能是竭宰,使數(shù)值從0到600根據(jù)插值器的類型去變化空郊。 (int)animation.getAnimatedValue()得到的是0~600之間的值,這個數(shù)值的獲取是Interpolator和Evalutor作用的結(jié)果切揭。
- 0~600得到的值是否是勻速變化還是其他速度變化的狞甚,由Interpolator決定。
- animation.getAnimatedValue()得到的值是多少廓旬,什么類型由Evalutor決定哼审。
inInt(0,600) | 加速器 | 估值器 | 監(jiān)聽器返回 |
---|---|---|---|
設(shè)置數(shù)值區(qū)間 | Interpolator動畫比例 | 根據(jù)加速器的動畫比例算出實際值 | getAnimatedValue得到實際值 |
插值器/加速器 Interpolator
- 默認每10毫秒刷新一次
//線性加速器
public class LinearInterpolator implements Interpolator {
public LinearInterpolator() {}
public LinearInterpolator(Context context, AttributeSet attrs) {}
public float getInterpolation(float input) {
return input;
}
}
public interface Interpolator extends TimeInterpolator {}
參數(shù)input:是一個float類型谐腰,它取值范圍是0到1,表示當(dāng)前動畫的進度涩盾,取0時表示動畫剛開始十气,取1時表示動畫結(jié)束,取0.5時表示動畫中間的位置春霍,其它類推砸西。
返回值:表示當(dāng)前實際想要顯示的進度。取值可以超過1也可以小于0址儒,超過1表示已經(jīng)超過目標(biāo)值芹枷,小于0表示小于開始位置。
再重復(fù)一遍莲趣,input參數(shù)與任何我們設(shè)定的值沒關(guān)系鸳慈,只與時間有關(guān),隨著時間的增長喧伞,動畫的進度也自然的增加走芋,input參數(shù)就代表了當(dāng)前動畫的進度。而返回值則表示自定義后的動畫的當(dāng)前數(shù)值進度潘鲫。
上面代碼:為什么LinearInterpolator是線性勻速變化的呢翁逞?
因為插值器根據(jù)設(shè)置的總時間,每10ms刷新一次次舌,調(diào)用getInterpolation傳入當(dāng)前的進度熄攘,LinearInterpolator中原值返回了,沒有改變默認進度彼念。
看自定義加速器代碼對比:
public class MyInterpolator implements Interpolator {
/**
* input 是實際動畫執(zhí)行的時間比例 0~1
* newInput 你想讓動畫已經(jīng)執(zhí)行的比例 0~1。
* 注意:都是比例浅萧,而不是實際的值逐沙。
*
* setDuration(1000)情況下:前200ms走了3/4的路程比例,后800ms走了1/4的路程比例洼畅。
* 注意:這里輸出的是比例吩案,是路程比例,不是實際的路程值帝簇!
*/
@Override
public float getInterpolation(float input) {
if (input <= 0.2) {//后1/4的時間徘郭,輸出3/4的比例
float newInput = input*4;
return newInput;
}else {//后3/4的時間,輸出1/4的比例
float newInput = (float) (input - 0.2)/4 + 0.8f;
return newInput;
}
}
}
Evaluator 估值器
我們通過加速器得到的是動畫進度的比例丧肴,并不是實際的數(shù)值残揉,Evaluator就是轉(zhuǎn)換成實際值的地方。(ofInt(0,600)中加速器拿到的是動畫的比例值芋浮,估值器根據(jù)比例轉(zhuǎn)換成實際的值抱环。AnimatorUpdateListener監(jiān)聽器中拿到的實際數(shù)值,就是通過Evaluator轉(zhuǎn)換后的值。)
- 看下面系統(tǒng)Evaluator代碼:
//設(shè)置取值區(qū)間時setIntValues(0,600)/setFloatValues(0,600),這是系統(tǒng)方法镇草,會自動為我們設(shè)置相應(yīng)的類型的Evaluator眶痰。
public class IntEvaluator implements TypeEvaluator<Integer> {
public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
//fraction是在插值器中處理后的進度,在這里以此轉(zhuǎn)換成實際值梯啤。
int startInt = startValue;
return (int)(startInt + fraction * (endValue - startInt));
}
}
- 開下面自定義Evaluator代碼:
public class PointEvaluator implements TypeEvaluator<Point> {
@Override
public Point evaluate(float fraction, Point startValue, Point endValue) {
int radius = (int) (startValue.getRadius() + fraction*(endValue.getRadius() - startValue.getRadius()));
return new Point(radius);
}
}
public void doAnimation(){
//ValueAnimator animatior = ValueAnimator.ofObject(new PointEvaluator(), new Point(20), new Point(80));
//上下作用一樣竖伯,不可混用。
ValueAnimator animatior = new ValueAnimator();
animatior.setObjectValues(new Point(20), new Point(80));
animatior.setEvaluator(new PointEvaluator());
animatior.setDuration(2000);
animatior.setInterpolator(new BounceInterpolator());
animatior.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mPoint = (Point) animation.getAnimatedValue();
invalidate();
}
});
animatior.start();
}
關(guān)于取值范圍
- void setObjectValues(Object... values);
- void setIntValues(int... values);
- void setFloatValues(float... values);
animatior.setObjectValues(new Point(20), new Point(150),new Point(80), new Point(200), new Point(20), new Point(150));
animatior.setDuration(2000);
public class PointEvaluator implements TypeEvaluator<Point> {
@Override
public Point evaluate(float fraction, Point startValue, Point endValue) {
int radius = (int) (startValue.getRadius() + fraction*(endValue.getRadius() - startValue.getRadius()));
return new Point(radius);
}
}
看上面的代碼可以發(fā)現(xiàn)因宇,setObjetValue可以有n個值黔夭。但是Evaluator估值器中只有startValue和endValue。
26.698 evaluate: startPoint=20-endPoint=150-fraction=0.0
......
26.979 evaluate: startPoint=20-endPoint=150-fraction=0.994
26.995 evaluate: startPoint=150-endPoint=80-fraction=0.049999993
27.245 evaluate: startPoint=150-endPoint=80-fraction=0.92499995
27.262 evaluate: startPoint=150-endPoint=80-fraction=0.9844998
27.278 evaluate: startPoint=80-endPoint=200-fraction=0.043999884
......
27.546 evaluate: startPoint=80-endPoint=200-fraction=0.975
27.562 evaluate: startPoint=200-endPoint=20-fraction=0.03449991
......
27.828 evaluate: startPoint=200-endPoint=20-fraction=0.9689996
27.847 evaluate: startPoint=20-endPoint=150-fraction=0.02499974
......
28.112 evaluate: startPoint=20-endPoint=150-fraction=0.9595001
28.129 evaluate: startPoint=150-endPoint=80-fraction=0.018999936
......
28.179 evaluate: startPoint=150-endPoint=80-fraction=0.99399978
ke以發(fā)現(xiàn)羽嫡,設(shè)置取值范圍的時候本姥,有幾個參數(shù),就把setDuration(2000)的時間分為多少分杭棵,1&2/2&3 / 3&4...作為start/endValue婚惫。至于每份取得的時間比例,就看設(shè)置的插值器了魂爪。
tips
- ArgbEvalutor 顏色估值器先舷。