上一篇我們總結(jié)了補(bǔ)間動畫尚困,接下來我們來總結(jié)一下屬性動畫的用法。
自從android3.0 之后又有了屬性動畫PropertyAnimation瓦阐。屬性動畫的實(shí)現(xiàn)機(jī)制是通過對目標(biāo)對象進(jìn)行賦值并修改其“屬性”來實(shí)現(xiàn)的,這個怎么理解呢?假如我們通過屬性動畫來移動一個textview搀暑,那么這個textview就是真正的移動了,而不再是僅僅在另外一個位置繪制了而已跨琳,即是控件的真實(shí)位置移動了自点,而補(bǔ)間動畫則是在另外一個地方繪制了一個一模一樣的而已,真實(shí)位置還是在原來的地方脉让。
ValueAnimator
ValueAnimator是整個屬性動畫機(jī)制當(dāng)中最核心的一個類桂敛,前面我們已經(jīng)提到了,屬性動畫的運(yùn)行機(jī)制是通過不斷地對值進(jìn)行操作來實(shí)現(xiàn)的溅潜,而初始值和結(jié)束值之間的動畫過渡就是由ValueAnimator這個類來負(fù)責(zé)計算的术唬。它的內(nèi)部使用一種時間循環(huán)的機(jī)制來計算值與值之間的動畫過渡,我們只需要將初始值和結(jié)束值提供給ValueAnimator滚澜,并且告訴它動畫所需運(yùn)行的時長粗仓,那么ValueAnimator就會自動幫我們完成從初始值平滑地過渡到結(jié)束值這樣的效果。除此之外,ValueAnimator還負(fù)責(zé)管理動畫的播放次數(shù)借浊、播放模式塘淑、以及對動畫設(shè)置監(jiān)聽器等。
*ValueAnimator anim = ValueAnimator.ofFloat(0f, 5f, 3f, 10f); *然后再開啟動畫即可蚂斤。當(dāng)然ValueAnimtor還有兩個常用方法存捺,即:ValueAnimator.ofInt(),ValueAnimator.ofObject()曙蒸,除此之外捌治,我們還可以調(diào)用setStartDelay()方法來設(shè)置動畫延遲播放的時間,調(diào)用setRepeatCount()和setRepeatMode()方法來設(shè)置動畫循環(huán)播放的次數(shù)以及循環(huán)播放的模式纽窟,循環(huán)模式包括RESTART和REVERSE兩種肖油,分別表示重新播放和倒序播放的意思。
下邊通過一個例子來介紹valueAnimator的使用:
private void vlueAnim() {
ValueAnimator anmator = ValueAnimator.ofFloat(1f, 0f, 1f, 0f);
anmator.setStartDelay(1000); //設(shè)置延時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);//動態(tài)更新textview的透明值
}
});
anmator.start();
}
這就是在監(jiān)聽器中通過得到的動畫值的變化來更新View的相關(guān)屬性师倔,從而有動畫效果构韵。
效果如下:
ObjectAnimator
ObjectAnimator與ValueAnimator的區(qū)別:
1、構(gòu)造方法與ObjectAnimator類似趋艘,ObjectAnimator繼承自ValueAnimtor疲恢。
2、與ObjectAnimator的區(qū)別在于ValueAnimator構(gòu)造函數(shù)的參數(shù)中不包含執(zhí)行該動畫“屬性”信息和對象瓷胧,只有動畫的值變化起始值和結(jié)束值显拳。
3、優(yōu)點(diǎn):結(jié)合動畫更新監(jiān)聽onAnimationUpdate使用搓萧,可以在回調(diào)中不斷更新View的多個屬性杂数,使用起來更加靈活。
ObjectAnimator可能才是我們最常接觸到的類瘸洛,因?yàn)閂alueAnimator只不過是對值進(jìn)行了一個平滑的動畫過渡揍移。而ObjectAnimator則就不同了,它是可以直接對任意對象的任意屬性進(jìn)行動畫操作的反肋,比如說View的alpha屬性那伐。
不過雖說ObjectAnimator會更加常用一些,但是它其實(shí)是繼承自ValueAnimator的石蔗,底層的動畫實(shí)現(xiàn)機(jī)制也是基于ValueAnimator來完成的罕邀,因此ValueAnimator仍然是整個屬性動畫當(dāng)中最核心的一個類。那么既然是繼承關(guān)系养距,說明ValueAnimator中可以使用的方法在ObjectAnimator中也是可以正常使用的诉探。
將textview 在3秒內(nèi),由常規(guī)變?yōu)橥该髟僮優(yōu)槌R?guī):
ObjectAnimator anim = ObjectAnimator.ofFloat(tv1, "alpha", 1f, 0f, 1f);
anim.setDuration(3000);//持續(xù)時間
anim.start();
將textview 在5秒內(nèi)360度旋轉(zhuǎn):
ObjectAnimator anim = ObjectAnimator.ofFloat(tv1, "rotation", 0f, 360f);
anim.setDuration(3000);
anim.start();
實(shí)現(xiàn)復(fù)合動畫功能主要需要借助AnimatorSet這個類棍厌,這個類提供了一個play()方法肾胯,如果我們向這個方法中傳入一個Animator對象(ValueAnimator或ObjectAnimator)將會返回一個AnimatorSet.Builder的實(shí)例竖席,AnimatorSet.Builder中包括以下四個方法:
after(Animator anim) 將現(xiàn)有動畫插入到該傳入的動畫(就是anim)之后執(zhí)行
after(long delay) 將現(xiàn)有動畫延遲指定毫秒后執(zhí)行
before(Animator anim) 將現(xiàn)有動畫插入到該傳入的動畫(就是anim)之前執(zhí)行
with(Animator anim) 將現(xiàn)有動畫和傳入的動畫同時執(zhí)行
好的,有了這四個方法阳液,我們就可以實(shí)現(xiàn)復(fù)合動畫了怕敬,先向上平移揣炕,然后旋轉(zhuǎn)同時改變透明值和縮放帘皿,就可以這樣做:
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); //先執(zhí)行anim4,再同時執(zhí)行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) {
//動畫結(jié)束,do sthing...
}
@Override
public void onAnimationCancel(Animator animation) {
}
@Override
public void onAnimationRepeat(Animator animation) {
}
});
// animset.setInterpolator(new OvershootInterpolator());
animset.start();
}
效果如下:
在很多時候丁恭,我們希望可以監(jiān)聽到動畫的各種事件曹动,比如動畫何時開始,何時結(jié)束牲览,然后在開始或者結(jié)束的時候去執(zhí)行一些邏輯處理墓陈。這個功能是完全可以實(shí)現(xiàn)的,Animator類當(dāng)中提供了一個addListener()方法第献,這個方法接收一個AnimatorListener贡必,我們只需要去實(shí)現(xiàn)這個AnimatorListener就可以監(jiān)聽動畫的各種事件了。
大家已經(jīng)知道庸毫,ObjectAnimator是繼承自ValueAnimator的仔拟,而ValueAnimator又是繼承自Animator的,因此不管是ValueAnimator還是ObjectAnimator都是可以使用addListener()這個方法的飒赃。另外AnimatorSet也是繼承自Animator的利花,因此addListener()這個方法算是個通用的方法。屬性動畫的基本用法就是這些了.不僅補(bǔ)間動畫可以使用插值器载佳,當(dāng)然屬性動畫也可以加入插值器動畫炒事。
加入插值器:
TranslateAnimation down = new TranslateAnimation(0, 0, -300, 0);//位移動畫,從button的上方300像素位置開始
down.setFillAfter(true);//設(shè)置動畫固定結(jié)束后位置
down.setInterpolator(new BounceInterpolator()); //彈跳動畫,要其它效果的當(dāng)然也可以設(shè)置為其它的值
down.setDuration(2000); //持續(xù)時間
btn_login.startAnimation(down);
btn_register.startAnimation(down);
效果如下:
更多插值器的用法可以用時候在慢慢了解蔫慧。挠乳。。