一切動畫盡在掌握之中
圖片發自簡書App
我們熟悉的Frame動畫和Tween動畫是Android 3.0之前的,這邊就不講解了。今天我要講的是從3.0開始引入的Property動畫。
Property動畫抓住三個核心概念
1.ValueAnimator
2.ObjectAnimator
3.ViewPropertyAnimator
然后在ValueAnimator中抓住一下兩個概念
1.TypeEvaluator
2.TimeInterpolator
可以說,搞清楚以上5點,一切動畫盡在掌握之中
ValueAnimator
ValueAnimator是整個屬性動畫機制當中最核心的一個類,屬性動畫的運行機制是通過不斷地對值進行操作來實現的,而初始值和結束值之間的動畫過渡就是由ValueAnimator這個類來負責計算的。
ValueAnimator anim = ValueAnimator.ofFloat(0f, 1f);
anim.setDuration(300);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float currentValue = (float) animation.getAnimatedValue();
Log.d("TAG", "cuurent value is " + currentValue);
}
});
anim.start();
ObjectAnimator
相比于ValueAnimator,ObjectAnimator可能才是我們最常接觸到的類,因為ValueAnimator只不過是對值進行了一個平滑的動畫過渡,但我們實際使用到這種功能的場景好像并不多。而ObjectAnimator則就不同了,它是可以直接對任意對象的任意屬性進行動畫操作的,比如說View的alpha、rotation、translationX和scaleY這幾個值,分別可以完成淡入淡出、旋轉、水平移動、垂直縮放這幾種動畫。
ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f, 1f);
animator.setDuration(5000);
animator.start();
AnimatorSet
AnimatorSet 提供了一個把多個動畫組合成一個組合的機制,并可設置組中動畫的時序關系,如同時播放,順序播放等。
- after(Animator anim) 將現有動畫插入到傳入的動畫之后執行
- after(long delay) 將現有動畫延遲指定毫秒后執行
- before(Animator anim) 將現有動畫插入到傳入的動畫之前執行
- with(Animator anim) 將現有動畫和傳入的動畫同時執行
ObjectAnimator moveIn = ObjectAnimator.ofFloat(textview, "translationX", -500f, 0f);
ObjectAnimator rotate = ObjectAnimator.ofFloat(textview, "rotation", 0f, 360f);
ObjectAnimator fadeInOut = ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f, 1f);
AnimatorSet animSet = new AnimatorSet();
animSet.play(rotate).with(fadeInOut).after(moveIn);
animSet.setDuration(5000);
animSet.start();
TypeEvalutors
evaluate()方法當中傳入了三個參數,第一個參數fraction非常重要,這個參數用于表示動畫的完成度的,我們應該根據它來計算當前動畫的值應該是多少,第二第三個參數分別表示動畫的初始值和結束值。那么下面代碼的邏輯就比較清晰了,用結束值減去初始值,算出它們之間的差值,然后乘以fraction這個系數,再加上初始值,那么就得到當前動畫的值了。
public class FloatEvaluator implements TypeEvaluator {
public Object evaluate(float fraction, Object startValue, Object endValue) {
float startFloat = ((Number) startValue).floatValue();
return startFloat + fraction * (((Number) endValue).floatValue() - startFloat);}
}
TimeInterpolator
Time interplator定義了屬性值變化的方式,如線性均勻改變,開始慢然后逐漸快等。在Property Animation中是TimeInterplator,在View Animation中是Interplator,這兩個是一樣的,在3.0之前只有Interplator,3.0之后實現代碼轉移至了TimeInterplator。Interplator繼承自TimeInterplator,內部沒有任何其他代碼。
- AccelerateInterpolator 加速,開始時慢中間加速
- DecelerateInterpolator 減速,開始時快然后減速
- AccelerateDecelerateInterolator 先加速后減速,開始結束時慢,中間加速
- AnticipateInterpolator 反向 ,先向相反方向改變一段再加速播放
- AnticipateOvershootInterpolator 反向加回彈,先向相反方向改變,再加速播放
- BounceInterpolator 跳躍,快到目的值時值會跳躍
- CycleIinterpolator 循環,動畫循環一定次數,值的改變為一正弦函數
- LinearInterpolator 線性,線性均勻改變
- OvershottInterpolator 回彈,最后超出目的值然后緩慢改變到目的值
private void startAnimation() {
Point startPoint = new Point(getWidth() / 2, RADIUS);
Point endPoint = new Point(getWidth() / 2, getHeight() - RADIUS);
ValueAnimator anim = ValueAnimator.ofObject(new PointEvaluator(), startPoint, endPoint);
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
currentPoint = (Point) animation.getAnimatedValue();
invalidate();
}
});
anim.setInterpolator(new BounceInterpolator());
anim.setDuration(3000);
anim.start();
}
ViewPropertyAnimator
ViewPropertyAnimator其實算不上什么高級技巧,它的用法格外的簡單,只不過和前面所學的所有屬性動畫的知識不同,它并不是在3.0系統當中引入的,而是在3.1系統當中附增的一個新的功能。
textview.animate().x(500).y(500).setDuration(5000);
源碼上傳在 GitHub
來自:http://www.jianshu.com/p/2232d566e935