ValueAnimator動(dòng)畫實(shí)現(xiàn)機(jī)制分析

ValueAnimator基于Choreographer frame callback 通過(guò)判斷當(dāng)前時(shí)間缨硝,調(diào)用View相關(guān)屬性摩钙,刷新UI實(shí)現(xiàn)動(dòng)畫效果。
其中核心是AnimationHandler查辩。AnimationHandler胖笛, 是一個(gè)靜態(tài)單例Handler供所有的Animator調(diào)用,內(nèi)部基于Choreographer周期callback更新UI frame宜岛,使用ThreadLocal方式實(shí)現(xiàn)同步长踊。
其中AnimationFrameCallbackProvider抽象了封裝Choreographer的接口,用戶可以自實(shí)現(xiàn)基于其他形式的刷新接口谬返,因?yàn)镃horeographer是基于實(shí)際硬件的UI刷新機(jī)制接口之斯,自定義適用于非硬件形式的測(cè)試日杈。
postFrameCallback(Choreographer.FrameCallback callback)
postCommitCallback(Runnable runnable) {

而內(nèi)部類MyFrameCallbackProvider作為默認(rèn)封裝Choreographer處理動(dòng)畫的機(jī)制Provider接口

那如何實(shí)現(xiàn)動(dòng)畫的機(jī)制呢遣铝?答案是向Choreographer注冊(cè)FrameCallback ,每次到frameTime時(shí)執(zhí)行動(dòng)畫刷新UI,再注冊(cè)莉擒,當(dāng)前接口
private final Choreographer.FrameCallback mFrameCallback = new Choreographer.FrameCallback() {
@Override
public void doFrame(long frameTimeNanos) {
doAnimationFrame(getProvider().getFrameTime());
if (mAnimationCallbacks.size() > 0) {
getProvider().postFrameCallback(this);
}
}
};

其中doAnimationFrame就是我們的動(dòng)畫執(zhí)行函數(shù)接口酿炸,那我們需要對(duì)上層動(dòng)畫抽象執(zhí)行動(dòng)畫的函數(shù)接口。doAnimationFrame處理所有實(shí)現(xiàn)AnimationFrameCallback 接口的doAnimationFrame()
interface AnimationFrameCallback {
boolean doAnimationFrame(long frameTime)
}

AnimationHandle維護(hù)frame callback隊(duì)列涨冀,
private final ArrayList<AnimationFrameCallback> mAnimationCallbacks =
new ArrayList<>();

AnimationHandler向上提供api
addAnimationFrameCallback
removeCallback

addAnimationFrameCallback提供注冊(cè)AnimationFrameCallback接口填硕,當(dāng)上層第一次向Provider注冊(cè)時(shí),添加默認(rèn)的mFrameCallback接口鹿鳖,觸發(fā)Choreographer callback機(jī)制扁眯。

removeCallback移除注冊(cè)AnimationFrameCallback接口

由上所知,我們?cè)倏碫alueAnimator恰恰實(shí)現(xiàn)了AnimationFrameCallback接口翅帜,內(nèi)部調(diào)用getAnimationHandler()姻檀,基于AnimationHandler實(shí)現(xiàn)動(dòng)畫機(jī)制。
我們看下ValueAnimator的簡(jiǎn)單使用方法:
ValueAnimator animator = ValueAnimator.ofInt(500);
animator.setDuration(1000);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int value = (int) animation.getAnimatedValue();
mView.setX(value);
}
});
animator.start();

發(fā)現(xiàn)主要做了兩步動(dòng)作:
1 配置動(dòng)畫參數(shù)
2 添加回調(diào)函數(shù)涝滴,收到值后執(zhí)行動(dòng)畫的具體實(shí)現(xiàn)绣版。

第二點(diǎn)我們可以猜測(cè)該回調(diào)必定在AnimationFrameCallback的doAnimationFrame中被執(zhí)行。
我們順藤摸瓜查看其邏輯歼疮,果然如此!
doAnimationFrame
animateBasedOnTime
animateValue
mUpdateListeners.get(i).onAnimationUpdate(this);

以上我們大致了解了ValueAnimator的整個(gè)動(dòng)畫實(shí)現(xiàn)機(jī)制杂抽,關(guān)于ProvertyValue,插值器, KeyFrame等的實(shí)現(xiàn)機(jī)制本文不再贅述韩脏。

源碼分析總計(jì):ValueAnimator很好的抽象了動(dòng)畫的邏輯機(jī)制缩麸,功能定義職責(zé)清晰,值得學(xué)習(xí)參考赡矢。
1 AnimationHandler封裝Choreographer的相關(guān)接口杭朱,并抽象動(dòng)畫提供接口方便用戶自定義擴(kuò)展和測(cè)試 AnimationFrameCallbackProvider
2 AnimationHandler向上抽象動(dòng)畫調(diào)用接口AnimationFrameCallback愚屁,方便動(dòng)畫擴(kuò)展。
3 ValueAnimator實(shí)現(xiàn)AnimationFrameCallback痕檬,單例調(diào)用AnimationHandler霎槐,實(shí)現(xiàn)doAnimationFrame 實(shí)現(xiàn)動(dòng)畫。
4 ValueAnimator專注動(dòng)畫的控制梦谜,實(shí)現(xiàn)start, stop, resume等接口

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末丘跌,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子唁桩,更是在濱河造成了極大的恐慌闭树,老刑警劉巖牵舵,帶你破解...
    沈念sama閱讀 221,273評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件基跑,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡立帖,警方通過(guò)查閱死者的電腦和手機(jī)单山,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門碍现,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人米奸,你說(shuō)我怎么就攤上這事昼接。” “怎么了悴晰?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,709評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵慢睡,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我铡溪,道長(zhǎng)漂辐,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,520評(píng)論 1 296
  • 正文 為了忘掉前任棕硫,我火速辦了婚禮髓涯,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘饲帅。我一直安慰自己复凳,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,515評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布灶泵。 她就那樣靜靜地躺著育八,像睡著了一般。 火紅的嫁衣襯著肌膚如雪赦邻。 梳的紋絲不亂的頭發(fā)上髓棋,一...
    開(kāi)封第一講書(shū)人閱讀 52,158評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼按声。 笑死膳犹,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的签则。 我是一名探鬼主播须床,決...
    沈念sama閱讀 40,755評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼渐裂!你這毒婦竟也來(lái)了豺旬?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,660評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤柒凉,失蹤者是張志新(化名)和其女友劉穎族阅,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體膝捞,經(jīng)...
    沈念sama閱讀 46,203評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡坦刀,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,287評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蔬咬。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片鲤遥。...
    茶點(diǎn)故事閱讀 40,427評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖计盒,靈堂內(nèi)的尸體忽然破棺而出渴频,到底是詐尸還是另有隱情芽丹,我是刑警寧澤北启,帶...
    沈念sama閱讀 36,122評(píng)論 5 349
  • 正文 年R本政府宣布,位于F島的核電站拔第,受9級(jí)特大地震影響咕村,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蚊俺,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,801評(píng)論 3 333
  • 文/蒙蒙 一懈涛、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧泳猬,春花似錦批钠、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,272評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至忙上,卻和暖如春拷呆,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,393評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工茬斧, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留腰懂,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,808評(píng)論 3 376
  • 正文 我出身青樓项秉,卻偏偏與公主長(zhǎng)得像绣溜,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子娄蔼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,440評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 1. 前言 上一篇文章《Android Animation運(yùn)行原理詳解》介紹了插間動(dòng)畫的原理涮毫,而Android3....
    SparkInLee閱讀 13,625評(píng)論 5 52
  • Android在3.0版本中引入了新的動(dòng)畫實(shí)現(xiàn):屬性動(dòng)畫。我們一般稱之為Animator贷屎。這種動(dòng)畫通過(guò)變更控件屬性...
    非墨Zero閱讀 821評(píng)論 0 0
  • 本文假定你已經(jīng)對(duì)屬性動(dòng)畫有了一定的了解罢防,至少使用過(guò)屬性動(dòng)畫。下面我們就從屬性動(dòng)畫最簡(jiǎn)單的使用開(kāi)始唉侄。 ObjectA...
    楊偉喬閱讀 642評(píng)論 0 0
  • 【Android 動(dòng)畫】 動(dòng)畫分類補(bǔ)間動(dòng)畫(Tween動(dòng)畫)幀動(dòng)畫(Frame 動(dòng)畫)屬性動(dòng)畫(Property ...
    Rtia閱讀 6,173評(píng)論 1 38
  • 一咒吐、前言 關(guān)于什么是動(dòng)畫,動(dòng)畫的相關(guān)概念等等這里就不講了属划。這里僅表述一下個(gè)人觀點(diǎn)恬叹,個(gè)人認(rèn)知是:1.動(dòng)畫增加了 UI...
    仰簡(jiǎn)閱讀 8,369評(píng)論 7 36