動(dòng)畫分類:
- 1 幀動(dòng)畫
- 2 補(bǔ)間動(dòng)畫 alpha(淡入淡出)攒霹,translate(位移)恢准,scale(縮放大小)粹断,rotate(旋轉(zhuǎn))
- 3 屬性動(dòng)畫
1.ViewPropertyAnimator
view.animate().translationX(300);
1.OjectAnimator
使用方式:
1.如果是自定義控件,需要添加setter/getter方法所刀;
2.用 ObjectAnimator.ofXXX() 創(chuàng)建 ObjectAnimator 對(duì)象衙荐;
3.用 start() 方法執(zhí)行動(dòng)畫。
final float radius = dpToPixel(80);
//自定義View的屬性 需要提供get set 方法 setter 方法記得加 invalidate()
public float getProgress() {
return progress;
}
public void setProgress(float progress) {
this.progress = progress;
invalidate();
}
@Override
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
float centerX = getWidth() / 2; float centerY = getHeight() / 2;
paint.setColor(Color.parseColor("#E91E63"));
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStrokeWidth(15)浮创;
arcRectF.set(centerX - radius, centerY - radius, centerX + radius, centerY + radius);
canvas.drawArc(arcRectF, 135, progress * 2.7f, false, paint);
paint.setColor(Color.WHITE);
paint.setStyle(Paint.Style.FILL);
canvas.drawText((int) progress + "%", centerX, centerY - (paint.ascent() + paint.descent()) / 2, paint);
}
// 創(chuàng)建 ObjectAnimator 對(duì)象 progress為自定義屬性
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(view, "progress", 0, 65);
objectAnimator.setDuration(3000);
objectAnimator.setInterpolator(new FastOutSlowInInterpolator()); //速度設(shè)置器
objectAnimator.start(); // 執(zhí)行動(dòng)畫
通用功能
- setDuration(int duration) 設(shè)置時(shí)長
// imageView1: 500 毫秒
imageView1.animate()
.translationX(500)
.setDuration(500);
// imageView2: 2 秒
ObjectAnimator animator = ObjectAnimator.ofFloat(
imageView2, "translationX", 500);
animator.setDuration(2000);
animator.start();
- setInterpolator(Interpolator interpolator) 設(shè)置 Interpolator
Interpolator就是速度設(shè)置器忧吟。
// imageView1: 線性 Interpolator,勻速
imageView1.animate()
.translationX(500)
.setInterpolator(new LinearInterpolator());
// imageView: 帶施法前搖和回彈的 Interpolator
ObjectAnimator animator = ObjectAnimator.ofFloat(
imageView2, "translationX", 500);
animator.setInterpolator(new AnticipateOvershootInterpolator());
animator.start();
HenCoder 自定義繪制的第 1-6 期:屬性動(dòng)畫(上手篇)
- AccelerateDecelerateInterpolator 先加速再減速(默認(rèn)的 Interpolator)
- FastOutSlowInInterpolator 先加速再減速
- LinearInterpolator 勻速
- AccelerateInterpolator 持續(xù)加速 離場效果斩披,飛出視野
- FastOutLinearInInterpolator 加速運(yùn)動(dòng) (貝塞爾曲線)
- DecelerateInterpolator 持續(xù)減速直到 0 入場效果 飛入視野
- AnticipateInterpolator 先回拉一下再進(jìn)行正常動(dòng)畫軌跡
- OvershootInterpolator 動(dòng)畫會(huì)超過目標(biāo)值一些溜族,然后再彈回來。
- AnticipateOvershootInterpolator 開始前回拉垦沉,最后超過一些然后回彈
- BounceInterpolator 在目標(biāo)值處彈跳煌抒。有點(diǎn)像玻璃球掉在地板上的效果。
- CycleInterpolator 正弦 / 余弦曲線厕倍,不過它和 AccelerateDecelerateInterpolator 的區(qū)別是寡壮,它可以自定義曲線的周期,所以動(dòng)畫可以不到終點(diǎn)就結(jié)束讹弯,也可以到達(dá)終點(diǎn)后回彈况既,回彈的次數(shù)由曲線的周期決定,曲線的周期由 CycleInterpolator() 構(gòu)造方法的參數(shù)決定组民。
- PathInterpolator 自定義動(dòng)畫完成度 / 時(shí)間完成度曲線棒仍。
3.設(shè)置監(jiān)聽器
給動(dòng)畫設(shè)置監(jiān)聽器,可以在關(guān)鍵時(shí)刻得到反饋臭胜,從而及時(shí)做出合適的操作降狠,例如在動(dòng)畫的屬性更新時(shí)同步更新其他數(shù)據(jù),或者在動(dòng)畫結(jié)束后回收資源等庇楞。
設(shè)置監(jiān)聽器的方法, ViewPropertyAnimator 和 ObjectAnimator 略微不一樣: ViewPropertyAnimator 用的是 setListener() 和 setUpdateListener() 方法否纬,可以設(shè)置一個(gè)監(jiān)聽器吕晌,要移除監(jiān)聽器時(shí)通過 set[Update]Listener(null) 填 null 值來移除;而 ObjectAnimator 則是用 addListener() 和 addUpdateListener() 來添加一個(gè)或多個(gè)監(jiān)聽器临燃,移除監(jiān)聽器則是通過 remove[Update]Listener() 來指定移除對(duì)象睛驳。
另外,由于 ObjectAnimator 支持使用 pause() 方法暫停膜廊,所以它還多了一個(gè) addPauseListener() / removePauseListener() 的支持乏沸;而 ViewPropertyAnimator 則獨(dú)有 withStartAction() 和 withEndAction() 方法,可以設(shè)置一次性的動(dòng)畫開始或結(jié)束的監(jiān)聽爪瓜。
3.1 ViewPropertyAnimator.setListener() / ObjectAnimator.addListener()
這兩個(gè)方法的名稱不一樣蹬跃,可以設(shè)置的監(jiān)聽器數(shù)量也不一樣,但它們的參數(shù)類型都是 AnimatorListener铆铆,所以本質(zhì)上其實(shí)都是一樣的蝶缀。 AnimatorListener 共有 4 個(gè)回調(diào)方法:
3.1.1 onAnimationStart(Animator animation)
當(dāng)動(dòng)畫開始執(zhí)行時(shí)丹喻,這個(gè)方法被調(diào)用。
3.1.2 onAnimationEnd(Animator animation)
當(dāng)動(dòng)畫結(jié)束時(shí)翁都,這個(gè)方法被調(diào)用碍论。
3.1.3 onAnimationCancel(Animator animation)
當(dāng)動(dòng)畫被通過 cancel() 方法取消時(shí),這個(gè)方法被調(diào)用柄慰。
需要說明一下的是鳍悠,就算動(dòng)畫被取消,onAnimationEnd() 也會(huì)被調(diào)用坐搔。所以當(dāng)動(dòng)畫被取消時(shí)藏研,如果設(shè)置了 AnimatorListener,那么 onAnimationCancel() 和 onAnimationEnd() 都會(huì)被調(diào)用薯蝎。onAnimationCancel() 會(huì)先于 onAnimationEnd() 被調(diào)用遥倦。
3.1.4 onAnimationRepeat(Animator animation)
當(dāng)動(dòng)畫通過 setRepeatMode() / setRepeatCount() 或 repeat() 方法重復(fù)執(zhí)行時(shí),這個(gè)方法被調(diào)用占锯。
由于 ViewPropertyAnimator 不支持重復(fù)袒哥,所以這個(gè)方法對(duì) ViewPropertyAnimator 相當(dāng)于無效。
3.2 ViewPropertyAnimator.setUpdateListener() / ObjectAnimator.addUpdateListener()
和上面 3.1 的兩個(gè)方法一樣消略,這兩個(gè)方法雖然名稱和可設(shè)置的監(jiān)聽器數(shù)量不一樣堡称,但本質(zhì)其實(shí)都一樣的,它們的參數(shù)都是 AnimatorUpdateListener艺演。它只有一個(gè)回調(diào)方法:onAnimationUpdate(ValueAnimator animation)却紧。
3.2.1 onAnimationUpdate(ValueAnimator animation)
當(dāng)動(dòng)畫的屬性更新時(shí)(不嚴(yán)謹(jǐn)?shù)恼f,即每過 10 毫秒胎撤,動(dòng)畫的完成度更新時(shí))晓殊,這個(gè)方法被調(diào)用。
方法的參數(shù)是一個(gè) ValueAnimator伤提,ValueAnimator 是 ObjectAnimator 的父類巫俺,也是 ViewPropertyAnimator 的內(nèi)部實(shí)現(xiàn),所以這個(gè)參數(shù)其實(shí)就是 ViewPropertyAnimator 內(nèi)部的那個(gè) ValueAnimator肿男,或者對(duì)于 ObjectAnimator 來說就是它自己本身介汹。
ValueAnimator 有很多方法可以用,它可以查看當(dāng)前的動(dòng)畫完成度舶沛、當(dāng)前的屬性值等等嘹承。不過 ValueAnimator 是下一期才講的內(nèi)容,所以這期就不多說了如庭。
3.3 ObjectAnimator.addPauseListener()
由于 ObjectAnimator.pause() 是下期的內(nèi)容叹卷,所以這個(gè)方法在這期就不講了。當(dāng)然,如果你有興趣的話豪娜,現(xiàn)在就了解一下也可以餐胀。
3.3 ViewPropertyAnimator.withStartAction/EndAction()
這兩個(gè)方法是 ViewPropertyAnimator 的獨(dú)有方法。它們和 set/addListener() 中回調(diào)的 onAnimationStart() / onAnimationEnd() 相比起來的不同主要有兩點(diǎn):
withStartAction() / withEndAction() 是一次性的瘤载,在動(dòng)畫執(zhí)行結(jié)束后就自動(dòng)棄掉了否灾,就算之后再重用 ViewPropertyAnimator 來做別的動(dòng)畫,用它們?cè)O(shè)置的回調(diào)也不會(huì)再被調(diào)用鸣奔。而 set/addListener() 所設(shè)置的 AnimatorListener 是持續(xù)有效的墨技,當(dāng)動(dòng)畫重復(fù)執(zhí)行時(shí),回調(diào)總會(huì)被調(diào)用挎狸。
withEndAction() 設(shè)置的回調(diào)只有在動(dòng)畫正常結(jié)束時(shí)才會(huì)被調(diào)用扣汪,而在動(dòng)畫被取消時(shí)不會(huì)被執(zhí)行。這點(diǎn)和 AnimatorListener.onAnimationEnd() 的行為是不一致的锨匆。