上一篇我們總結了補間動畫,接下來我們來總結一下屬性動畫的用法。
自從android3.0 之后又有了屬性動畫PropertyAnimation。屬性動畫的實現機制是通過對目標對象進行賦值并修改其“屬性”來實現的,這個怎么理解呢?假如我們通過屬性動畫來移動一個textview,那么這個textview就是真正的移動了,而不再是僅僅在另外一個位置繪制了而已,即是控件的真實位置移動了,而補間動畫則是在另外一個地方繪制了一個一模一樣的而已,真實位置還是在原來的地方。
ValueAnimator
ValueAnimator是整個屬性動畫機制當中最核心的一個類,前面我們已經提到了,屬性動畫的運行機制是通過不斷地對值進行操作來實現的,而初始值和結束值之間的動畫過渡就是由ValueAnimator這個類來負責計算的。它的內部使用一種時間循環的機制來計算值與值之間的動畫過渡,我們只需要將初始值和結束值提供給ValueAnimator,并且告訴它動畫所需運行的時長,那么ValueAnimator就會自動幫我們完成從初始值平滑地過渡到結束值這樣的效果。除此之外,ValueAnimator還負責管理動畫的播放次數、播放模式、以及對動畫設置監聽器等。
*ValueAnimator anim = ValueAnimator.ofFloat(0f, 5f, 3f, 10f); *然后再開啟動畫即可。當然ValueAnimtor還有兩個常用方法,即:ValueAnimator.ofInt(),ValueAnimator.ofObject(),除此之外,我們還可以調用setStartDelay()方法來設置動畫延遲播放的時間,調用setRepeatCount()和setRepeatMode()方法來設置動畫循環播放的次數以及循環播放的模式,循環模式包括RESTART和REVERSE兩種,分別表示重新播放和倒序播放的意思。
下邊通過一個例子來介紹valueAnimator的使用:
private void vlueAnim() {
ValueAnimator anmator = ValueAnimator.ofFloat(1f, 0f, 1f, 0f);
anmator.setStartDelay(1000); //設置延時1秒后開始動畫
anmator.setDuration(5000);
anmator.setRepeatCount(10);
anmator.setRepeatMode(ValueAnimator.RESTART);
anmator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = (float) animation.getAnimatedValue();
tv.setAlpha(value);//動態更新textview的透明值
}
});
anmator.start();
}
這就是在監聽器中通過得到的動畫值的變化來更新View的相關屬性,從而有動畫效果。
效果如下:
ObjectAnimator
ObjectAnimator與ValueAnimator的區別:
1、構造方法與ObjectAnimator類似,ObjectAnimator繼承自ValueAnimtor。
2、與ObjectAnimator的區別在于ValueAnimator構造函數的參數中不包含執行該動畫“屬性”信息和對象,只有動畫的值變化起始值和結束值。
3、優點:結合動畫更新監聽onAnimationUpdate使用,可以在回調中不斷更新View的多個屬性,使用起來更加靈活。
ObjectAnimator可能才是我們最常接觸到的類,因為ValueAnimator只不過是對值進行了一個平滑的動畫過渡。而ObjectAnimator則就不同了,它是可以直接對任意對象的任意屬性進行動畫操作的,比如說View的alpha屬性。
不過雖說ObjectAnimator會更加常用一些,但是它其實是繼承自ValueAnimator的,底層的動畫實現機制也是基于ValueAnimator來完成的,因此ValueAnimator仍然是整個屬性動畫當中最核心的一個類。那么既然是繼承關系,說明ValueAnimator中可以使用的方法在ObjectAnimator中也是可以正常使用的。
將textview 在3秒內,由常規變為透明再變為常規:
ObjectAnimator anim = ObjectAnimator.ofFloat(tv1, "alpha", 1f, 0f, 1f);
anim.setDuration(3000);//持續時間
anim.start();
將textview 在5秒內360度旋轉:
ObjectAnimator anim = ObjectAnimator.ofFloat(tv1, "rotation", 0f, 360f);
anim.setDuration(3000);
anim.start();
實現復合動畫功能主要需要借助AnimatorSet這個類,這個類提供了一個play()方法,如果我們向這個方法中傳入一個Animator對象(ValueAnimator或ObjectAnimator)將會返回一個AnimatorSet.Builder的實例,AnimatorSet.Builder中包括以下四個方法:
after(Animator anim) 將現有動畫插入到該傳入的動畫(就是anim)之后執行
after(long delay) 將現有動畫延遲指定毫秒后執行
before(Animator anim) 將現有動畫插入到該傳入的動畫(就是anim)之前執行
with(Animator anim) 將現有動畫和傳入的動畫同時執行
好的,有了這四個方法,我們就可以實現復合動畫了,先向上平移,然后旋轉同時改變透明值和縮放,就可以這樣做:
private void objectAnim() {
ObjectAnimator anim1 = ObjectAnimator.ofFloat(tv1, "alpha", 0.5f, 1f, 0.5f, 1f);
ObjectAnimator anim2 = ObjectAnimator.ofFloat(tv1, "rotation", 0f, 360f);
ObjectAnimator anim3 = ObjectAnimator.ofFloat(tv1, "scaleY", 1f, 3f, 1f);
ObjectAnimator anim4 = ObjectAnimator.ofFloat(tv1, "translationY", 0f, -100f); //Y軸平移
// ObjectAnimator anim4 = ObjectAnimator.ofFloat(tv1, "translationX", 0f, 50f); //X軸平移
AnimatorSet animset = new AnimatorSet(); //定義一個AnimatorSet對象
animset.play(anim1).with(anim2).with(anim3).after(anim4); //先執行anim4,再同時執行anim1、anim2、anim3
animset.setDuration(6000);
animset.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
//動畫開始,do sthing...
}
@Override
public void onAnimationEnd(Animator animation) {
//動畫結束,do sthing...
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
// animset.setInterpolator(new OvershootInterpolator());
animset.start();
}
效果如下:
在很多時候,我們希望可以監聽到動畫的各種事件,比如動畫何時開始,何時結束,然后在開始或者結束的時候去執行一些邏輯處理。這個功能是完全可以實現的,Animator類當中提供了一個addListener()方法,這個方法接收一個AnimatorListener,我們只需要去實現這個AnimatorListener就可以監聽動畫的各種事件了。
大家已經知道,ObjectAnimator是繼承自ValueAnimator的,而ValueAnimator又是繼承自Animator的,因此不管是ValueAnimator還是ObjectAnimator都是可以使用addListener()這個方法的。另外AnimatorSet也是繼承自Animator的,因此addListener()這個方法算是個通用的方法。屬性動畫的基本用法就是這些了.不僅補間動畫可以使用插值器,當然屬性動畫也可以加入插值器動畫。
加入插值器:
TranslateAnimation down = new TranslateAnimation(0, 0, -300, 0);//位移動畫,從button的上方300像素位置開始
down.setFillAfter(true);//設置動畫固定結束后位置
down.setInterpolator(new BounceInterpolator()); //彈跳動畫,要其它效果的當然也可以設置為其它的值
down.setDuration(2000); //持續時間
btn_login.startAnimation(down);
btn_register.startAnimation(down);
效果如下:
更多插值器的用法可以用時候在慢慢了解。。。