屬性動畫的基本用法

在手機上去實現(xiàn)一些動畫效果算是件比較炫酷的事情玻驻,因此Android系統(tǒng)在一開始的時候就給我們提供了兩種實現(xiàn)動畫效果的方式,逐幀動畫(frame-by-frame animation)和補間動畫(tweened animation)。逐幀動畫的工作原理很簡單,其實就是將一個完整的動畫拆分成一張張單獨的圖片莽鸭,然后再將它們連貫起來進行播放,類似于動畫片的工作原理吃靠。補間動畫則是可以對View進行一系列的動畫操作硫眨,包括淡入淡出、縮放巢块、平移礁阁、旋轉四種。

然而自Android 3.0版本開始族奢,系統(tǒng)給我們提供了一種全新的動畫模式姥闭,屬性動畫(property animation),它的功能非常強大越走,彌補了之前補間動畫的一些缺陷棚品,幾乎是可以完全替代掉補間動畫了。對于逐幀動畫和補間動畫的用法廊敌,我不想再多講铜跑,它們的技術已經(jīng)比較老了,而且網(wǎng)上資料也非常多骡澈,那么今天我們這篇文章的主題就是對Android屬性動畫進行一次完全解析锅纺。

為什么要引入屬性動畫?

Android之前的補間動畫機制其實還算是比較健全的肋殴,在android.view.animation包下面有好多的類可以供我們操作伞广,來完成一系列的動畫效果拣帽,比如說對View進行移動、縮放嚼锄、旋轉和淡入淡出减拭,并且我們還可以借助AnimationSet來將這些動畫效果組合起來使用,除此之外還可以通過配置Interpolator來控制動畫的播放速度等等等等区丑。那么這里大家可能要產(chǎn)生疑問了拧粪,既然之前的動畫機制已經(jīng)這么健全了,為什么還要引入屬性動畫呢沧侥?

其實上面所謂的健全都是相對的可霎,如果你的需求中只需要對View進行移動、縮放宴杀、旋轉和淡入淡出操作癣朗,那么補間動畫確實已經(jīng)足夠健全了。但是很顯然旺罢,這些功能是不足以覆蓋所有的場景的旷余,一旦我們的需求超出了移動、縮放扁达、旋轉和淡入淡出這四種對View的操作正卧,那么補間動畫就不能再幫我們忙了,也就是說它在功能和可擴展方面都有相當大的局限性跪解,那么下面我們就來看看補間動畫所不能勝任的場景炉旷。

注意上面我在介紹補間動畫的時候都有使用“對View進行操作”這樣的描述,沒錯叉讥,補間動畫是只能夠作用在View上的窘行。也就是說,我們可以對一個Button图仓、TextView罐盔、甚至是LinearLayout、或者其它任何繼承自View的組件進行動畫操作透绩,但是如果我們想要對一個非View的對象進行動畫操作翘骂,抱歉,補間動畫就幫不上忙了帚豪√季梗可能有的朋友會感到不能理解,我怎么會需要對一個非View的對象進行動畫操作呢狸臣?這里我舉一個簡單的例子莹桅,比如說我們有一個自定義的View,在這個View當中有一個Point對象用于管理坐標,然后在onDraw()方法當中就是根據(jù)這個Point對象的坐標值來進行繪制的诈泼。也就是說懂拾,如果我們可以對Point對象進行動畫操作,那么整個自定義View的動畫效果就有了铐达。顯然岖赋,補間動畫是不具備這個功能的,這是它的第一個缺陷瓮孙。

然后補間動畫還有一個缺陷唐断,就是它只能夠實現(xiàn)移動、縮放杭抠、旋轉和淡入淡出這四種動畫操作脸甘,那如果我們希望可以對View的背景色進行動態(tài)地改變呢?很遺憾偏灿,我們只能靠自己去實現(xiàn)了丹诀。說白了,之前的補間動畫機制就是使用硬編碼的方式來完成的翁垂,功能限定死就是這些铆遭,基本上沒有任何擴展性可言。

最后沮峡,補間動畫還有一個致命的缺陷疚脐,就是它只是改變了View的顯示效果而已亿柑,而不會真正去改變View的屬性邢疙。什么意思呢?比如說望薄,現(xiàn)在屏幕的左上角有一個按鈕疟游,然后我們通過補間動畫將它移動到了屏幕的右下角,現(xiàn)在你可以去嘗試點擊一下這個按鈕痕支,點擊事件是絕對不會觸發(fā)的颁虐,因為實際上這個按鈕還是停留在屏幕的左上角,只不過補間動畫將這個按鈕繪制到了屏幕的右下角而已卧须。

也正是因為這些原因另绩,Android開發(fā)團隊決定在3.0版本當中引入屬性動畫這個功能,那么屬性動畫是不是就把上述的問題全部解決掉了花嘶?下面我們就來一起看一看笋籽。

新引入的屬性動畫機制已經(jīng)不再是針對于View來設計的了,也不限定于只能實現(xiàn)移動椭员、縮放车海、旋轉和淡入淡出這幾種動畫操作,同時也不再只是一種視覺上的動畫效果了隘击。它實際上是一種不斷地對值進行操作的機制侍芝,并將值賦值到指定對象的指定屬性上研铆,可以是任意對象的任意屬性。所以我們仍然可以將一個View進行移動或者縮放州叠,但同時也可以對自定義View中的Point對象進行動畫操作了棵红。我們只需要告訴系統(tǒng)動畫的運行時長,需要執(zhí)行哪種類型的動畫咧栗,以及動畫的初始值和結束值窄赋,剩下的工作就可以全部交給系統(tǒng)去完成了。

既然屬性動畫的實現(xiàn)機制是通過對目標對象進行賦值并修改其屬性來實現(xiàn)的楼熄,那么之前所說的按鈕顯示的問題也就不復存在了忆绰,如果我們通過屬性動畫來移動一個按鈕,那么這個按鈕就是真正的移動了可岂,而不再是僅僅在另外一個位置繪制了而已错敢。

好了,介紹了這么多缕粹,相信大家已經(jīng)對屬性動畫有了一個最基本的認識了稚茅,下面我們就來開始學習一下屬性動畫的用法。

ValueAnimator

ValueAnimator是整個屬性動畫機制當中最核心的一個類平斩,前面我們已經(jīng)提到了亚享,屬性動畫的運行機制是通過不斷地對值進行操作來實現(xiàn)的,而初始值和結束值之間的動畫過渡就是由ValueAnimator這個類來負責計算的绘面。它的內部使用一種時間循環(huán)的機制來計算值與值之間的動畫過渡欺税,我們只需要將初始值和結束值提供給ValueAnimator,并且告訴它動畫所需運行的時長揭璃,那么ValueAnimator就會自動幫我們完成從初始值平滑地過渡到結束值這樣的效果晚凿。除此之外,ValueAnimator還負責管理動畫的播放次數(shù)瘦馍、播放模式歼秽、以及對動畫設置監(jiān)聽器等,確實是一個非常重要的類情组。

但是ValueAnimator的用法卻一點都不復雜燥筷,我們先從最簡單的功能看起吧,比如說想要將一個值從0平滑過渡到1院崇,時長300毫秒肆氓,就可以這樣寫:

[java]view plaincopy

ValueAnimator?anim?=?ValueAnimator.ofFloat(0f,?1f);

anim.setDuration(300);

anim.start();

怎么樣?很簡單吧亚脆,調用ValueAnimator的ofFloat()方法就可以構建出一個ValueAnimator的實例做院,ofFloat()方法當中允許傳入多個float類型的參數(shù),這里傳入0和1就表示將值從0平滑過渡到1,然后調用ValueAnimator的setDuration()方法來設置動畫運行的時長键耕,最后調用start()方法啟動動畫寺滚。

用法就是這么簡單,現(xiàn)在如果你運行一下上面的代碼屈雄,動畫就會執(zhí)行了村视。可是這只是一個將值從0過渡到1的動畫酒奶,又看不到任何界面效果蚁孔,我們怎樣才能知道這個動畫是不是已經(jīng)真正運行了呢?這就需要借助監(jiān)聽器來實現(xiàn)了惋嚎,如下所示:

[java]view plaincopy

ValueAnimator?anim?=?ValueAnimator.ofFloat(0f,?1f);

anim.setDuration(300);

anim.addUpdateListener(newValueAnimator.AnimatorUpdateListener()?{

@Override

publicvoidonAnimationUpdate(ValueAnimator?animation)?{

floatcurrentValue?=?(float)?animation.getAnimatedValue();

Log.d("TAG","cuurent?value?is?"+?currentValue);

}

});

anim.start();

可以看到杠氢,這里我們通過addUpdateListener()方法來添加一個動畫的監(jiān)聽器,在動畫執(zhí)行的過程中會不斷地進行回調另伍,我們只需要在回調方法當中將當前的值取出并打印出來鼻百,就可以知道動畫有沒有真正運行了。運行上述代碼摆尝,控制臺打印如下所示:

從打印日志的值我們就可以看出温艇,ValueAnimator確實已經(jīng)在正常工作了,值在300毫秒的時間內從0平滑過渡到了1堕汞,而這個計算工作就是由ValueAnimator幫助我們完成的勺爱。另外ofFloat()方法當中是可以傳入任意多個參數(shù)的,因此我們還可以構建出更加復雜的動畫邏輯讯检,比如說將一個值在5秒內從0過渡到5琐鲁,再過渡到3,再過渡到10视哑,就可以這樣寫:

[java]view plaincopy

ValueAnimator?anim?=?ValueAnimator.ofFloat(0f,?5f,?3f,?10f);

anim.setDuration(5000);

anim.start();

當然也許你并不需要小數(shù)位數(shù)的動畫過渡绣否,可能你只是希望將一個整數(shù)值從0平滑地過渡到100誊涯,那么也很簡單挡毅,只需要調用ValueAnimator的ofInt()方法就可以了,如下所示:

[java]view plaincopy

ValueAnimator?anim?=?ValueAnimator.ofInt(0,100);

ValueAnimator當中最常用的應該就是ofFloat()和ofInt()這兩個方法了暴构,另外還有一個ofObject()方法跪呈,我會在下篇文章進行講解。

那么除此之外取逾,我們還可以調用setStartDelay()方法來設置動畫延遲播放的時間耗绿,調用setRepeatCount()和setRepeatMode()方法來設置動畫循環(huán)播放的次數(shù)以及循環(huán)播放的模式,循環(huán)模式包括RESTART和REVERSE兩種砾隅,分別表示重新播放和倒序播放的意思误阻。這些方法都很簡單,我就不再進行詳細講解了。

ObjectAnimator

相比于ValueAnimator究反,ObjectAnimator可能才是我們最常接觸到的類寻定,因為ValueAnimator只不過是對值進行了一個平滑的動畫過渡,但我們實際使用到這種功能的場景好像并不多精耐。而ObjectAnimator則就不同了狼速,它是可以直接對任意對象的任意屬性進行動畫操作的,比如說View的alpha屬性卦停。

不過雖說ObjectAnimator會更加常用一些向胡,但是它其實是繼承自ValueAnimator的,底層的動畫實現(xiàn)機制也是基于ValueAnimator來完成的惊完,因此ValueAnimator仍然是整個屬性動畫當中最核心的一個類僵芹。那么既然是繼承關系,說明ValueAnimator中可以使用的方法在ObjectAnimator中也是可以正常使用的小槐,它們的用法也非常類似淮捆,這里如果我們想要將一個TextView在5秒中內從常規(guī)變換成全透明,再從全透明變換成常規(guī)本股,就可以這樣寫:

[java]view plaincopy

ObjectAnimator?animator?=?ObjectAnimator.ofFloat(textview,"alpha",?1f,?0f,?1f);

animator.setDuration(5000);

animator.start();

可以看到攀痊,我們還是調用了ofFloat()方法來去創(chuàng)建一個ObjectAnimator的實例,只不過ofFloat()方法當中接收的參數(shù)有點變化了拄显。這里第一個參數(shù)要求傳入一個object對象苟径,我們想要對哪個對象進行動畫操作就傳入什么,這里我傳入了一個textview躬审。第二個參數(shù)是想要對該對象的哪個屬性進行動畫操作棘街,由于我們想要改變TextView的不透明度,因此這里傳入"alpha"承边。后面的參數(shù)就是不固定長度了遭殉,想要完成什么樣的動畫就傳入什么值,這里傳入的值就表示將TextView從常規(guī)變換成全透明博助,再從全透明變換成常規(guī)险污。之后調用setDuration()方法來設置動畫的時長,然后調用start()方法啟動動畫富岳,效果如下圖所示:

學會了這一個用法之后蛔糯,其它的用法我們就可以舉一反三了,那比如說我們想要將TextView進行一次360度的旋轉窖式,就可以這樣寫:

[java]view plaincopy

ObjectAnimator?animator?=?ObjectAnimator.ofFloat(textview,"rotation",?0f,?360f);

animator.setDuration(5000);

animator.start();

可以看到蚁飒,這里我們將第二個參數(shù)改成了"rotation",然后將動畫的初始值和結束值分別設置成0和360萝喘,現(xiàn)在運行一下代碼淮逻,效果如下圖所示:

那么如果想要將TextView先向左移出屏幕琼懊,然后再移動回來,就可以這樣寫:

[java]view plaincopy

floatcurTranslationX?=?textview.getTranslationX();

ObjectAnimator?animator?=?ObjectAnimator.ofFloat(textview,"translationX",?curTranslationX,?-500f,?curTranslationX);

animator.setDuration(5000);

animator.start();

這里我們先是調用了TextView的getTranslationX()方法來獲取到當前TextView的translationX的位置爬早,然后ofFloat()方法的第二個參數(shù)傳入"translationX"肩碟,緊接著后面三個參數(shù)用于告訴系統(tǒng)TextView應該怎么移動,現(xiàn)在運行一下代碼凸椿,效果如下圖所示:

然后我們還可以TextView進行縮放操作削祈,比如說將TextView在垂直方向上放大3倍再還原,就可以這樣寫:

[java]view plaincopy

ObjectAnimator?animator?=?ObjectAnimator.ofFloat(textview,"scaleY",?1f,?3f,?1f);

animator.setDuration(5000);

animator.start();

這里將ofFloat()方法的第二個參數(shù)改成了"scaleY"脑漫,表示在垂直方向上進行縮放髓抑,現(xiàn)在重新運行一下程序,效果如下圖所示:

到目前為止优幸,ObjectAnimator的用法還算是相當簡單吧吨拍,但是我相信肯定會有不少朋友現(xiàn)在心里都有同樣一個疑問,就是ofFloat()方法的第二個參數(shù)到底可以傳哪些值呢网杆?目前我們使用過了alpha羹饰、rotation、translationX和scaleY這幾個值碳却,分別可以完成淡入淡出队秩、旋轉、水平移動昼浦、垂直縮放這幾種動畫馍资,那么還有哪些值是可以使用的呢?其實這個問題的答案非常玄乎关噪,就是我們可以傳入任意的值到ofFloat()方法的第二個參數(shù)當中鸟蟹。任意的值?相信這很出乎大家的意料吧使兔,但事實就是如此建钥。因為ObjectAnimator在設計的時候就沒有針對于View來進行設計,而是針對于任意對象的虐沥,它所負責的工作就是不斷地向某個對象中的某個屬性進行賦值熊经,然后對象根據(jù)屬性值的改變再來決定如何展現(xiàn)出來。

那么比如說我們調用下面這樣一段代碼:

[java]view plaincopy

ObjectAnimator.ofFloat(textview,"alpha",?1f,?0f);

其實這段代碼的意思就是ObjectAnimator會幫我們不斷地改變textview對象中alpha屬性的值置蜀,從1f變化到0f奈搜。然后textview對象需要根據(jù)alpha屬性值的改變來不斷刷新界面的顯示,從而讓用戶可以看出淡入淡出的動畫效果盯荤。

那么textview對象中是不是有alpha屬性這個值呢?沒有焕盟,不僅textview沒有這個屬性秋秤,連它所有的父類也是沒有這個屬性的宏粤!這就奇怪了,textview當中并沒有alpha這個屬性灼卢,ObjectAnimator是如何進行操作的呢绍哎?其實ObjectAnimator內部的工作機制并不是直接對我們傳入的屬性名進行操作的,而是會去尋找這個屬性名對應的get和set方法鞋真,因此alpha屬性所對應的get和set方法應該就是:

[java]view plaincopy

publicvoidsetAlpha(floatvalue);

publicfloatgetAlpha();

那么textview對象中是否有這兩個方法呢崇堰?確實有,并且這兩個方法是由View對象提供的涩咖,也就是說不僅TextView可以使用這個屬性來進行淡入淡出動畫操作海诲,任何繼承自View的對象都可以的。

既然alpha是這個樣子檩互,相信大家一定已經(jīng)明白了特幔,前面我們所用的所有屬性都是這個工作原理,那么View當中一定也存在著setRotation()闸昨、getRotation()蚯斯、setTranslationX()、getTranslationX()饵较、setScaleY()拍嵌、getScaleY()這些方法,不信的話你可以到View當中去找一下循诉。

組合動畫

獨立的動畫能夠實現(xiàn)的視覺效果畢竟是相當有限的撰茎,因此將多個動畫組合到一起播放就顯得尤為重要。幸運的是打洼,Android團隊在設計屬性動畫的時候也充分考慮到了組合動畫的功能龄糊,因此提供了一套非常豐富的API來讓我們將多個動畫組合到一起。

實現(xiàn)組合動畫功能主要需要借助AnimatorSet這個類募疮,這個類提供了一個play()方法炫惩,如果我們向這個方法中傳入一個Animator對象(ValueAnimator或ObjectAnimator)將會返回一個AnimatorSet.Builder的實例,AnimatorSet.Builder中包括以下四個方法:

after(Animator anim) ? 將現(xiàn)有動畫插入到傳入的動畫之后執(zhí)行

after(long delay) ? 將現(xiàn)有動畫延遲指定毫秒后執(zhí)行

before(Animator anim) ? 將現(xiàn)有動畫插入到傳入的動畫之前執(zhí)行

with(Animator anim) ? 將現(xiàn)有動畫和傳入的動畫同時執(zhí)行

好的阿浓,有了這四個方法他嚷,我們就可以完成組合動畫的邏輯了,那么比如說我們想要讓TextView先從屏幕外移動進屏幕芭毙,然后開始旋轉360度筋蓖,旋轉的同時進行淡入淡出操作,就可以這樣寫:

[java]view plaincopy

ObjectAnimator?moveIn?=?ObjectAnimator.ofFloat(textview,"translationX",?-500f,?0f);

ObjectAnimator?rotate?=?ObjectAnimator.ofFloat(textview,"rotation",?0f,?360f);

ObjectAnimator?fadeInOut?=?ObjectAnimator.ofFloat(textview,"alpha",?1f,?0f,?1f);

AnimatorSet?animSet?=newAnimatorSet();

animSet.play(rotate).with(fadeInOut).after(moveIn);

animSet.setDuration(5000);

animSet.start();

可以看到退敦,這里我們先是把三個動畫的對象全部創(chuàng)建出來粘咖,然后new出一個AnimatorSet對象之后將這三個動畫對象進行播放排序,讓旋轉和淡入淡出動畫同時進行侈百,并把它們插入到了平移動畫的后面瓮下,最后是設置動畫時長以及啟動動畫翰铡。運行一下上述代碼,效果如下圖所示:

Animator監(jiān)聽器

在很多時候讽坏,我們希望可以監(jiān)聽到動畫的各種事件锭魔,比如動畫何時開始,何時結束路呜,然后在開始或者結束的時候去執(zhí)行一些邏輯處理迷捧。這個功能是完全可以實現(xiàn)的,Animator類當中提供了一個addListener()方法胀葱,這個方法接收一個AnimatorListener漠秋,我們只需要去實現(xiàn)這個AnimatorListener就可以監(jiān)聽動畫的各種事件了。

大家已經(jīng)知道巡社,ObjectAnimator是繼承自ValueAnimator的膛堤,而ValueAnimator又是繼承自Animator的,因此不管是ValueAnimator還是ObjectAnimator都是可以使用addListener()這個方法的晌该。另外AnimatorSet也是繼承自Animator的肥荔,因此addListener()這個方法算是個通用的方法。

添加一個監(jiān)聽器的代碼如下所示:

[java]view plaincopy

anim.addListener(newAnimatorListener()?{

@Override

publicvoidonAnimationStart(Animator?animation)?{

}

@Override

publicvoidonAnimationRepeat(Animator?animation)?{

}

@Override

publicvoidonAnimationEnd(Animator?animation)?{

}

@Override

publicvoidonAnimationCancel(Animator?animation)?{

}

});

可以看到朝群,我們需要實現(xiàn)接口中的四個方法燕耿,onAnimationStart()方法會在動畫開始的時候調用,onAnimationRepeat()方法會在動畫重復執(zhí)行的時候調用姜胖,onAnimationEnd()方法會在動畫結束的時候調用誉帅,onAnimationCancel()方法會在動畫被取消的時候調用。

但是也許很多時候我們并不想要監(jiān)聽那么多個事件右莱,可能我只想要監(jiān)聽動畫結束這一個事件蚜锨,那么每次都要將四個接口全部實現(xiàn)一遍就顯得非常繁瑣。沒關系慢蜓,為此Android提供了一個適配器類亚再,叫作AnimatorListenerAdapter,使用這個類就可以解決掉實現(xiàn)接口繁瑣的問題了晨抡,如下所示:

[java]view plaincopy

anim.addListener(newAnimatorListenerAdapter()?{

});

這里我們向addListener()方法中傳入這個適配器對象氛悬,由于AnimatorListenerAdapter中已經(jīng)將每個接口都實現(xiàn)好了,所以這里不用實現(xiàn)任何一個方法也不會報錯耘柱。那么如果我想監(jiān)聽動畫結束這個事件如捅,就只需要單獨重寫這一個方法就可以了,如下所示:

[java]view plaincopy

anim.addListener(newAnimatorListenerAdapter()?{

@Override

publicvoidonAnimationEnd(Animator?animation)?{

}

});

使用XML編寫動畫

我們可以使用代碼來編寫所有的動畫功能调煎,這也是最常用的一種做法镜遣。不過,過去的補間動畫除了使用代碼編寫之外也是可以使用XML編寫的汛蝙,因此屬性動畫也提供了這一功能烈涮,即通過XML來完成和代碼一樣的屬性動畫功能朴肺。

通過XML來編寫動畫可能會比通過代碼來編寫動畫要慢一些窖剑,但是在重用方面將會變得非常輕松坚洽,比如某個將通用的動畫編寫到XML里面,我們就可以在各個界面當中輕松去重用它西土。

如果想要使用XML來編寫動畫讶舰,首先要在res目錄下面新建一個animator文件夾,所有屬性動畫的XML文件都應該存放在這個文件夾當中需了。然后在XML文件中我們一共可以使用如下三種標簽:

?對應代碼中的ValueAnimator

?對應代碼中的ObjectAnimator

?對應代碼中的AnimatorSet

那么比如說我們想要實現(xiàn)一個從0到100平滑過渡的動畫跳昼,在XML當中就可以這樣寫:

[html]view plaincopy

android:valueFrom="0"

android:valueTo="100"

android:valueType="intType"/>

而如果我們想將一個視圖的alpha屬性從1變成0,就可以這樣寫:

[html]view plaincopy

android:valueFrom="1"

android:valueTo="0"

android:valueType="floatType"

android:propertyName="alpha"/>

其實XML編寫動畫在可讀性方面還是挺高的肋乍,上面的內容相信不用我做解釋大家也都看得懂吧鹅颊。

另外,我們也可以使用XML來完成復雜的組合動畫操作墓造,比如將一個視圖先從屏幕外移動進屏幕堪伍,然后開始旋轉360度,旋轉的同時進行淡入淡出操作觅闽,就可以這樣寫:

[html]view plaincopy

android:ordering="sequentially">

android:duration="2000"

android:propertyName="translationX"

android:valueFrom="-500"

android:valueTo="0"

android:valueType="floatType">

android:duration="3000"

android:propertyName="rotation"

android:valueFrom="0"

android:valueTo="360"

android:valueType="floatType">

android:duration="1500"

android:propertyName="alpha"

android:valueFrom="1"

android:valueTo="0"

android:valueType="floatType">

android:duration="1500"

android:propertyName="alpha"

android:valueFrom="0"

android:valueTo="1"

android:valueType="floatType">

這段XML實現(xiàn)的效果和我們剛才通過代碼來實現(xiàn)的組合動畫的效果是一模一樣的帝雇,每個參數(shù)的含義都非常清楚,相信大家都是一看就懂蛉拙,我就不再一一解釋了尸闸。

最后XML文件是編寫好了,那么我們如何在代碼中把文件加載進來并將動畫啟動呢孕锄?只需調用如下代碼即可:

[java]view plaincopy

Animator?animator?=?AnimatorInflater.loadAnimator(context,?R.animator.anim_file);

animator.setTarget(view);

animator.start();

調用AnimatorInflater的loadAnimator來將XML動畫文件加載進來吮廉,然后再調用setTarget()方法將這個動畫設置到某一個對象上面,最后再調用start()方法啟動動畫就可以了畸肆,就是這么簡單宦芦。


http://blog.csdn.net/guolin_blog/article/details/43536355

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市恼除,隨后出現(xiàn)的幾起案子踪旷,更是在濱河造成了極大的恐慌,老刑警劉巖豁辉,帶你破解...
    沈念sama閱讀 219,539評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件令野,死亡現(xiàn)場離奇詭異,居然都是意外死亡徽级,警方通過查閱死者的電腦和手機气破,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,594評論 3 396
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來餐抢,“玉大人现使,你說我怎么就攤上這事低匙。” “怎么了碳锈?”我有些...
    開封第一講書人閱讀 165,871評論 0 356
  • 文/不壞的土叔 我叫張陵顽冶,是天一觀的道長。 經(jīng)常有香客問我售碳,道長强重,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,963評論 1 295
  • 正文 為了忘掉前任贸人,我火速辦了婚禮间景,結果婚禮上,老公的妹妹穿的比我還像新娘艺智。我一直安慰自己倘要,他們只是感情好,可當我...
    茶點故事閱讀 67,984評論 6 393
  • 文/花漫 我一把揭開白布十拣。 她就那樣靜靜地躺著封拧,像睡著了一般。 火紅的嫁衣襯著肌膚如雪父晶。 梳的紋絲不亂的頭發(fā)上哮缺,一...
    開封第一講書人閱讀 51,763評論 1 307
  • 那天,我揣著相機與錄音甲喝,去河邊找鬼尝苇。 笑死,一個胖子當著我的面吹牛埠胖,可吹牛的內容都是我干的展融。 我是一名探鬼主播韩脑,決...
    沈念sama閱讀 40,468評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼陵珍,長吁一口氣:“原來是場噩夢啊……” “哼琼蚯!你這毒婦竟也來了?” 一聲冷哼從身側響起谋竖,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤红柱,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后蓖乘,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體锤悄,經(jīng)...
    沈念sama閱讀 45,850評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,002評論 3 338
  • 正文 我和宋清朗相戀三年嘉抒,在試婚紗的時候發(fā)現(xiàn)自己被綠了零聚。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,144評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖隶症,靈堂內的尸體忽然破棺而出政模,到底是詐尸還是另有隱情,我是刑警寧澤蚂会,帶...
    沈念sama閱讀 35,823評論 5 346
  • 正文 年R本政府宣布淋样,位于F島的核電站,受9級特大地震影響颂龙,放射性物質發(fā)生泄漏习蓬。R本人自食惡果不足惜纽什,卻給世界環(huán)境...
    茶點故事閱讀 41,483評論 3 331
  • 文/蒙蒙 一措嵌、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧芦缰,春花似錦企巢、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,026評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至探孝,卻和暖如春笋婿,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背顿颅。 一陣腳步聲響...
    開封第一講書人閱讀 33,150評論 1 272
  • 我被黑心中介騙來泰國打工缸濒, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人粱腻。 一個月前我還...
    沈念sama閱讀 48,415評論 3 373
  • 正文 我出身青樓庇配,卻偏偏與公主長得像,于是被迫代替她去往敵國和親绍些。 傳聞我的和親對象是個殘疾皇子捞慌,可洞房花燭夜當晚...
    茶點故事閱讀 45,092評論 2 355

推薦閱讀更多精彩內容