ValueAnimator 的用法
要實(shí)現(xiàn)一個(gè)從0到100的位移動(dòng)畫(huà)径玖,ValueAnimator會(huì)根據(jù)動(dòng)畫(huà)持續(xù)的總時(shí)間產(chǎn)生一個(gè)0~1時(shí)間因子,有了這樣一個(gè)時(shí)間因子纪挎。通過(guò)相應(yīng)的變幻期贫,就可以根據(jù)你的startValue和endValue來(lái)生成相應(yīng)的值。同時(shí)异袄,通過(guò)插值器的使用通砍,我們還可以進(jìn)一步控制每一個(gè)時(shí)間因子它產(chǎn)生值的一個(gè)變化速率。如果我們使用線性插值器烤蜕,那么它生成數(shù)值的時(shí)候封孙,就會(huì)形成一個(gè)線性變化,只要時(shí)間相同讽营,它的增量也相同虎忌。如果我們使用一個(gè)加速度的插值器,那么它的增量變化就會(huì)呈現(xiàn)一個(gè)二次曲線圖橱鹏。增長(zhǎng)率會(huì)越來(lái)越快膜蠢。由于我們的ValueAnimator并不響應(yīng)任何一個(gè)動(dòng)畫(huà)堪藐,也不能控制任何一個(gè)屬性,所以它并沒(méi)有ObjectAnimator使用的那么廣泛挑围。我們還是來(lái)看一下如何在程序中使用ValueAnimator吧庶橱。
ValueAnimator animator = ValueAnimator.ofInt(start, end);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
/**
* 通過(guò)這樣一個(gè)監(jiān)聽(tīng)事件,我們就可以獲取
* 到ValueAnimator每一步所產(chǎn)生的值贪惹。
*
* 通過(guò)調(diào)用getAnimatedValue()獲取到每個(gè)時(shí)間因子所產(chǎn)生的Value苏章。
* */
//獲取動(dòng)畫(huà)過(guò)程中的漸變值
int animatedValue = (int) animation.getAnimatedValue();
Log.w("wangwei", "--->" + animatedValue);
ViewGroup.LayoutParams layoutParams = last.getLayoutParams();
layoutParams.height = animatedValue;
last.setLayoutParams(layoutParams);
}
});
if (mAdapter.getItemCount() > 0) {
animator.setDuration(300);
animator.start();
}
objectAnimator的基礎(chǔ)用法,
如平移奏瞬、旋轉(zhuǎn)枫绅、縮放、漸變以及動(dòng)畫(huà)的集合硼端;至于objectAnimator(必須的有set get方法)和valueAnimator的詳細(xì)區(qū)別也可參考郭霖大神的動(dòng)畫(huà)詳解篇
2并淋、除此基本用法,還有估值器和插值器
(1)插值器:動(dòng)畫(huà)速率的變換珍昨,有點(diǎn)類似物理的加速度县耽,就是該變動(dòng)畫(huà)的速率的
(2)估值器:一般配合插值器使用,插值器返回因子镣典,起始值兔毙,結(jié)束值給估值器,估值器根據(jù)這個(gè)區(qū)間數(shù)據(jù)生成這個(gè)區(qū)間連續(xù)的數(shù)值兄春,而這寫(xiě)數(shù)值就是動(dòng)畫(huà)需要的屬性的值澎剥,使動(dòng)畫(huà)平滑過(guò)渡比如:ValueAnimator.ofFloat()方法就是實(shí)現(xiàn)了初始值與結(jié)束值之間的平滑過(guò)度,那么這個(gè)平滑過(guò)度是怎么做到的呢赶舆?其實(shí)就是系統(tǒng)內(nèi)置了一個(gè)FloatEvaluator哑姚,它通過(guò)計(jì)算告知?jiǎng)赢?huà)系統(tǒng)如何從初始值過(guò)度到結(jié)束值
我們都知道對(duì)于屬性動(dòng)畫(huà)可以對(duì)某個(gè)屬性做動(dòng)畫(huà),而插值器(TimeInterpolator)和估值器(TypeEvaluator)在其中扮演了重要角色芜茵,下面先了解下TimeInterpolator和TypeEvaluator叙量。
TimeInterpolator(時(shí)間插值器):
作用:根據(jù)時(shí)間流逝的百分比計(jì)算出當(dāng)前屬性值改變的百分比。
系統(tǒng)已有的插值器:
①LinearInterpolator(線性插值器):勻速動(dòng)畫(huà)九串。
②AccelerateDecelerateInterpolator(加速減速插值器):動(dòng)畫(huà)兩頭慢绞佩,中間快。
③DecelerateInterpolator(減速插值器):動(dòng)畫(huà)越來(lái)越慢蒸辆。
TypeEvaluator(類型估值算法征炼,即估值器):
作用:根據(jù)當(dāng)前屬性改變的百分比來(lái)計(jì)算改變后的屬性值析既。
系統(tǒng)已有的估值器:
①IntEvaluator:針對(duì)整型屬性
②FloatEvaluator:針對(duì)浮點(diǎn)型屬性
③ArgbEvaluator:針對(duì)Color屬性
那么TimeInterpolator和TypeEvaluator是怎么協(xié)同工作的呢躬贡?
它們是實(shí)現(xiàn)非勻速動(dòng)畫(huà)的重要手段。屬性動(dòng)畫(huà)是對(duì)屬性做動(dòng)畫(huà)眼坏,屬性要實(shí)現(xiàn)動(dòng)畫(huà)拂玻,首先由TimeInterpolator(插值器)根據(jù)時(shí)間流逝的百分比計(jì)算出當(dāng)前屬性值改變的百分比酸些,并且插值器將這個(gè)百分比返回,這個(gè)時(shí)候插值器的工作就完成了檐蚜。比如插值器返回的值是0.5魄懂,很顯然我們要的不是0.5,而是當(dāng)前屬性的值闯第,即當(dāng)前屬性變成了什么值市栗,這就需要估值器根據(jù)當(dāng)前屬性改變的百分比來(lái)計(jì)算改變后的屬性值,根據(jù)這個(gè)屬性值咳短,我們就可以設(shè)置當(dāng)前屬
做了一凡說(shuō)明填帽,直接上代碼:
1、透明度
RESTART:重新從頭開(kāi)始執(zhí)行咙好。
REVERSE:反方向執(zhí)行篡腌。
private void voidstartAlphaAnim(View view) {
ObjectAnimator animator = ObjectAnimator.ofFloat(view, "alpha", 0f, 1.0f);
animator.setDuration(3000);
animator.setRepeatCount(-1);
animator.setRepeatMode(ValueAnimator.REVERSE);
animator.start();
}
位移
private void startTranslationAnimtor(View mView) {
ObjectAnimator animator = ObjectAnimator.ofFloat(mView, "TranslationX", 0, 500);
animator.setDuration(3000);
animator.setRepeatCount(-1);
animator.setRepeatMode(ValueAnimator.REVERSE);
animator.start();
}
縮放
public static void playAnimationDaShang(View view) {
AnimatorSet animatorSetPeople = new AnimatorSet(); //多個(gè)動(dòng)畫(huà) 動(dòng)畫(huà)集
animatorSetPeople.setDuration(1000);
ObjectAnimator translationX = ObjectAnimator.ofFloat(view, "translationX", -110, 110, 0);
ObjectAnimator scaleX = ObjectAnimator.ofFloat(view, "scaleX", 1, 2, 1);//從原始狀態(tài)放大2倍再回到原始狀態(tài)
ObjectAnimator scaleY = ObjectAnimator.ofFloat(view, "scaleY", 1, 2, 1);
translationX.setRepeatCount(-1);//設(shè)置動(dòng)畫(huà)重復(fù)次數(shù)
translationX.setRepeatMode(ObjectAnimator.RESTART);//動(dòng)畫(huà)重復(fù)模式
translationX.setStartDelay(1000);//動(dòng)畫(huà)延時(shí)執(zhí)行
translationX.setInterpolator(new AccelerateInterpolator());//Interpolator可以定義動(dòng)畫(huà)播放的速度
/*after(Animator anim) 將現(xiàn)有動(dòng)畫(huà)插入到傳入的動(dòng)畫(huà)之后執(zhí)行
after(long delay) 將現(xiàn)有動(dòng)畫(huà)延遲指定毫秒后執(zhí)行
before(Animator anim) 將現(xiàn)有動(dòng)畫(huà)插入到傳入的動(dòng)畫(huà)之前執(zhí)行
with(Animator anim) 將現(xiàn)有動(dòng)畫(huà)和傳入的動(dòng)畫(huà)同時(shí)執(zhí)行*/
animatorSetPeople.play(translationX).before(scaleX).before(scaleY);
// animatorSetPeople.playTogether(translationX, scaleX, scaleY);
animatorSetPeople.start();
animatorSetPeople.end();
animatorSetPeople.cancel();
}
旋轉(zhuǎn)
/**
* 旋轉(zhuǎn)動(dòng)畫(huà)
*/
private void startRotationAnimtor(View mView) {
ObjectAnimator rotation = ObjectAnimator.ofFloat(mView, "Rotation", 0, 180);
// rotation.setRepeatCount(-1);
rotation.setRepeatMode(ValueAnimator.REVERSE);
rotation.setDuration(2000);
rotation.start();
}