寫的非常好叽唱,強烈推薦給大家
轉(zhuǎn)載請注明出處:http://blog.csdn.net/guolin_blog/article/details/43536355
在手機上去實現(xiàn)一些動畫效果算是件比較炫酷的事情杏节,因此Android系統(tǒng)在一開始的時候就給我們提供了兩種實現(xiàn)動畫效果的方式德召,逐幀動畫(frame-by-frame animation)和補間動畫(tweened animation)。逐幀動畫的工作原理很簡單,其實就是將一個完整的動畫拆分成一張張單獨的圖片,然后再將它們連貫起來進行播放壁公,類似于動畫片的工作原理。補間動畫則是可以對View進行一系列的動畫操作绅项,包括淡入淡出紊册、縮放、平移快耿、旋轉(zhuǎn)四種囊陡。
然而自Android 3.0版本開始芳绩,系統(tǒng)給我們提供了一種全新的動畫模式,屬性動畫(property animation)撞反,它的功能非常強大妥色,彌補了之前補間動畫的一些缺陷,幾乎是可以完全替代掉補間動畫了遏片。對于逐幀動畫和補間動畫的用法嘹害,我不想再多講,它們的技術(shù)已經(jīng)比較老了吮便,而且網(wǎng)上資料也非常多笔呀,那么今天我們這篇文章的主題就是對Android屬性動畫進行一次完全解析。
Android之前的補間動畫機制其實還算是比較健全的凿可,在android.view.animation包下面有好多的類可以供我們操作,來完成一系列的動畫效果授账,比如說對View進行移動、縮放惨驶、旋轉(zhuǎn)和淡入淡出白热,并且我們還可以借助AnimationSet來將這些動畫效果組合起來使用,除此之外還可以通過配置Interpolator來控制動畫的播放速度等等等等粗卜。那么這里大家可能要產(chǎn)生疑問了屋确,既然之前的動畫機制已經(jīng)這么健全了,為什么還要引入屬性動畫呢续扔?
其實上面所謂的健全都是相對的攻臀,如果你的需求中只需要對View進行移動、縮放纱昧、旋轉(zhuǎn)和淡入淡出操作刨啸,那么補間動畫確實已經(jīng)足夠健全了。但是很顯然识脆,這些功能是不足以覆蓋所有的場景的设联,一旦我們的需求超出了移動、縮放灼捂、旋轉(zhuǎn)和淡入淡出這四種對View的操作离例,那么補間動畫就不能再幫我們忙了,也就是說它在功能和可擴展方面都有相當大的局限性悉稠,那么下面我們就來看看補間動畫所不能勝任的場景宫蛆。
注意上面我在介紹補間動畫的時候都有使用“對View進行操作”這樣的描述,沒錯的猛,補間動畫是只能夠作用在View上的耀盗。也就是說辑甜,我們可以對一個Button、TextView袍冷、甚至是LinearLayout磷醋、或者其它任何繼承自View的組件進行動畫操作,但是如果我們想要對一個非View的對象進行動畫操作胡诗,抱歉邓线,補間動畫就幫不上忙了』突郑可能有的朋友會感到不能理解骇陈,我怎么會需要對一個非View的對象進行動畫操作呢?這里我舉一個簡單的例子瑰抵,比如說我們有一個自定義的View你雌,在這個View當中有一個Point對象用于管理坐標,然后在onDraw()方法當中就是根據(jù)這個Point對象的坐標值來進行繪制的二汛。也就是說婿崭,如果我們可以對Point對象進行動畫操作,那么整個自定義View的動畫效果就有了肴颊。顯然氓栈,補間動畫是不具備這個功能的,這是它的第一個缺陷婿着。
然后補間動畫還有一個缺陷授瘦,就是它只能夠?qū)崿F(xiàn)移動、縮放竟宋、旋轉(zhuǎn)和淡入淡出這四種動畫操作提完,那如果我們希望可以對View的背景色進行動態(tài)地改變呢?很遺憾丘侠,我們只能靠自己去實現(xiàn)了徒欣。說白了,之前的補間動畫機制就是使用硬編碼的方式來完成的婉陷,功能限定死就是這些帚称,基本上沒有任何擴展性可言。
最后秽澳,補間動畫還有一個致命的缺陷闯睹,就是它只是改變了View的顯示效果而已,而不會真正去改變View的屬性担神。什么意思呢楼吃?比如說,現(xiàn)在屏幕的左上角有一個按鈕,然后我們通過補間動畫將它移動到了屏幕的右下角孩锡,現(xiàn)在你可以去嘗試點擊一下這個按鈕酷宵,點擊事件是絕對不會觸發(fā)的,因為實際上這個按鈕還是停留在屏幕的左上角躬窜,只不過補間動畫將這個按鈕繪制到了屏幕的右下角而已浇垦。
也正是因為這些原因,Android開發(fā)團隊決定在3.0版本當中引入屬性動畫這個功能荣挨,那么屬性動畫是不是就把上述的問題全部解決掉了男韧?下面我們就來一起看一看。
新引入的屬性動畫機制已經(jīng)不再是針對于View來設計的了默垄,也不限定于只能實現(xiàn)移動此虑、縮放、旋轉(zhuǎn)和淡入淡出這幾種動畫操作口锭,同時也不再只是一種視覺上的動畫效果了朦前。它實際上是一種不斷地對值進行操作的機制,并將值賦值到指定對象的指定屬性上鹃操,可以是任意對象的任意屬性韭寸。所以我們?nèi)匀豢梢詫⒁粋€View進行移動或者縮放,但同時也可以對自定義View中的Point對象進行動畫操作了组民。我們只需要告訴系統(tǒng)動畫的運行時長棒仍,需要執(zhí)行哪種類型的動畫,以及動畫的初始值和結(jié)束值臭胜,剩下的工作就可以全部交給系統(tǒng)去完成了。
既然屬性動畫的實現(xiàn)機制是通過對目標對象進行賦值并修改其屬性來實現(xiàn)的癞尚,那么之前所說的按鈕顯示的問題也就不復存在了耸三,如果我們通過屬性動畫來移動一個按鈕,那么這個按鈕就是真正的移動了浇揩,而不再是僅僅在另外一個位置繪制了而已仪壮。
好了,介紹了這么多胳徽,相信大家已經(jīng)對屬性動畫有了一個最基本的認識了积锅,下面我們就來開始學習一下屬性動畫的用法。
ValueAnimator是整個屬性動畫機制當中最核心的一個類养盗,前面我們已經(jīng)提到了缚陷,屬性動畫的運行機制是通過不斷地對值進行操作來實現(xiàn)的,而初始值和結(jié)束值之間的動畫過渡就是由ValueAnimator這個類來負責計算的往核。它的內(nèi)部使用一種時間循環(huán)的機制來計算值與值之間的動畫過渡箫爷,我們只需要將初始值和結(jié)束值提供給ValueAnimator,并且告訴它動畫所需運行的時長,那么ValueAnimator就會自動幫我們完成從初始值平滑地過渡到結(jié)束值這樣的效果虎锚。除此之外硫痰,ValueAnimator還負責管理動畫的播放次數(shù)、播放模式窜护、以及對動畫設置監(jiān)聽器等效斑,確實是一個非常重要的類。
但是ValueAnimator的用法卻一點都不復雜柱徙,我們先從最簡單的功能看起吧缓屠,比如說想要將一個值從0平滑過渡到1,時長300毫秒坐搔,就可以這樣寫:
[java]view plaincopy
ValueAnimator?anim?=?ValueAnimator.ofFloat(0f,?1f);
anim.setDuration(300);
anim.start();
怎么樣藏研?很簡單吧,調(diào)用ValueAnimator的ofFloat()方法就可以構(gòu)建出一個ValueAnimator的實例概行,ofFloat()方法當中允許傳入多個float類型的參數(shù)蠢挡,這里傳入0和1就表示將值從0平滑過渡到1,然后調(diào)用ValueAnimator的setDuration()方法來設置動畫運行的時長凳忙,最后調(diào)用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í)行的過程中會不斷地進行回調(diào)近尚,我們只需要在回調(diào)方法當中將當前的值取出并打印出來蠕啄,就可以知道動畫有沒有真正運行了。運行上述代碼戈锻,控制臺打印如下所示:
從打印日志的值我們就可以看出歼跟,ValueAnimator確實已經(jīng)在正常工作了,值在300毫秒的時間內(nèi)從0平滑過渡到了1格遭,而這個計算工作就是由ValueAnimator幫助我們完成的哈街。另外ofFloat()方法當中是可以傳入任意多個參數(shù)的,因此我們還可以構(gòu)建出更加復雜的動畫邏輯如庭,比如說將一個值在5秒內(nèi)從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帝牡,那么也很簡單,只需要調(diào)用ValueAnimator的ofInt()方法就可以了蒙揣,如下所示:
[java]view plaincopy
ValueAnimator?anim?=?ValueAnimator.ofInt(0,100);
ValueAnimator當中最常用的應該就是ofFloat()和ofInt()這兩個方法了靶溜,另外還有一個ofObject()方法,我會在下篇文章進行講解懒震。
那么除此之外罩息,我們還可以調(diào)用setStartDelay()方法來設置動畫延遲播放的時間,調(diào)用setRepeatCount()和setRepeatMode()方法來設置動畫循環(huán)播放的次數(shù)以及循環(huán)播放的模式个扰,循環(huán)模式包括RESTART和REVERSE兩種瓷炮,分別表示重新播放和倒序播放的意思。這些方法都很簡單递宅,我就不再進行詳細講解了娘香。
相比于ValueAnimator,ObjectAnimator可能才是我們最常接觸到的類办龄,因為ValueAnimator只不過是對值進行了一個平滑的動畫過渡烘绽,但我們實際使用到這種功能的場景好像并不多。而ObjectAnimator則就不同了俐填,它是可以直接對任意對象的任意屬性進行動畫操作的安接,比如說View的alpha屬性。
不過雖說ObjectAnimator會更加常用一些英融,但是它其實是繼承自ValueAnimator的盏檐,底層的動畫實現(xiàn)機制也是基于ValueAnimator來完成的,因此ValueAnimator仍然是整個屬性動畫當中最核心的一個類驶悟。那么既然是繼承關(guān)系糯笙,說明ValueAnimator中可以使用的方法在ObjectAnimator中也是可以正常使用的,它們的用法也非常類似撩银,這里如果我們想要將一個TextView在5秒中內(nèi)從常規(guī)變換成全透明,再從全透明變換成常規(guī)豺憔,就可以這樣寫:
[java]view plaincopy
ObjectAnimator?animator?=?ObjectAnimator.ofFloat(textview,"alpha",?1f,?0f,?1f);
animator.setDuration(5000);
animator.start();
可以看到额获,我們還是調(diào)用了ofFloat()方法來去創(chuàng)建一個ObjectAnimator的實例,只不過ofFloat()方法當中接收的參數(shù)有點變化了恭应。這里第一個參數(shù)要求傳入一個object對象抄邀,我們想要對哪個對象進行動畫操作就傳入什么,這里我傳入了一個textview昼榛。第二個參數(shù)是想要對該對象的哪個屬性進行動畫操作境肾,由于我們想要改變TextView的不透明度,因此這里傳入"alpha"。后面的參數(shù)就是不固定長度了奥喻,想要完成什么樣的動畫就傳入什么值偶宫,這里傳入的值就表示將TextView從常規(guī)變換成全透明,再從全透明變換成常規(guī)环鲤。之后調(diào)用setDuration()方法來設置動畫的時長纯趋,然后調(diào)用start()方法啟動動畫,效果如下圖所示:
學會了這一個用法之后冷离,其它的用法我們就可以舉一反三了吵冒,那比如說我們想要將TextView進行一次360度的旋轉(zhuǎn),就可以這樣寫:
[java]view plaincopy
ObjectAnimator?animator?=?ObjectAnimator.ofFloat(textview,"rotation",?0f,?360f);
animator.setDuration(5000);
animator.start();
可以看到西剥,這里我們將第二個參數(shù)改成了"rotation"痹栖,然后將動畫的初始值和結(jié)束值分別設置成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();
這里我們先是調(diào)用了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這幾個值柜候,分別可以完成淡入淡出搞动、旋轉(zhuǎn)、水平移動渣刷、垂直縮放這幾種動畫鹦肿,那么還有哪些值是可以使用的呢?其實這個問題的答案非常玄乎辅柴,就是我們可以傳入任意的值到ofFloat()方法的第二個參數(shù)當中箩溃。任意的值瞭吃?相信這很出乎大家的意料吧,但事實就是如此涣旨。因為ObjectAnimator在設計的時候就沒有針對于View來進行設計歪架,而是針對于任意對象的,它所負責的工作就是不斷地向某個對象中的某個屬性進行賦值开泽,然后對象根據(jù)屬性值的改變再來決定如何展現(xiàn)出來牡拇。
那么比如說我們調(diào)用下面這樣一段代碼:
[java]view plaincopy
ObjectAnimator.ofFloat(textview,"alpha",?1f,?0f);
其實這段代碼的意思就是ObjectAnimator會幫我們不斷地改變textview對象中alpha屬性的值,從1f變化到0f穆律。然后textview對象需要根據(jù)alpha屬性值的改變來不斷刷新界面的顯示惠呼,從而讓用戶可以看出淡入淡出的動畫效果。
那么textview對象中是不是有alpha屬性這個值呢峦耘?沒有剔蹋,不僅textview沒有這個屬性,連它所有的父類也是沒有這個屬性的辅髓!這就奇怪了泣崩,textview當中并沒有alpha這個屬性,ObjectAnimator是如何進行操作的呢洛口?其實ObjectAnimator內(nèi)部的工作機制并不是直接對我們傳入的屬性名進行操作的矫付,而是會去尋找這個屬性名對應的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當中去找一下。
獨立的動畫能夠?qū)崿F(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先從屏幕外移動進屏幕,然后開始旋轉(zhuǎn)360度吼过,旋轉(zhuǎn)的同時進行淡入淡出操作锐秦,就可以這樣寫:
[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對象之后將這三個動畫對象進行播放排序酱床,讓旋轉(zhuǎn)和淡入淡出動畫同時進行,并把它們插入到了平移動畫的后面趟佃,最后是設置動畫時長以及啟動動畫扇谣。運行一下上述代碼,效果如下圖所示:
在很多時候闲昭,我們希望可以監(jiān)聽到動畫的各種事件罐寨,比如動畫何時開始,何時結(jié)束序矩,然后在開始或者結(jié)束的時候去執(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
public void onAnimationStart(Animator?animation)?{
}
@Override
public void onAnimationRepeat(Animator?animation)?{
}
@Override
public void onAnimationEnd(Animator?animation)?{
}
@Override
public void onAnimationCancel(Animator?animation)?{
}
});
可以看到珠叔,我們需要實現(xiàn)接口中的四個方法蝎宇,onAnimationStart()方法會在動畫開始的時候調(diào)用,onAnimationRepeat()方法會在動畫重復執(zhí)行的時候調(diào)用祷安,onAnimationEnd()方法會在動畫結(jié)束的時候調(diào)用姥芥,onAnimationCancel()方法會在動畫被取消的時候調(diào)用。
但是也許很多時候我們并不想要監(jiān)聽那么多個事件汇鞭,可能我只想要監(jiān)聽動畫結(jié)束這一個事件凉唐,那么每次都要將四個接口全部實現(xiàn)一遍就顯得非常繁瑣庸追。沒關(guān)系,為此Android提供了一個適配器類台囱,叫作AnimatorListenerAdapter淡溯,使用這個類就可以解決掉實現(xiàn)接口繁瑣的問題了,如下所示:
[java]view plaincopy
anim.addListener(newAnimatorListenerAdapter()?{
});
這里我們向addListener()方法中傳入這個適配器對象簿训,由于AnimatorListenerAdapter中已經(jīng)將每個接口都實現(xiàn)好了咱娶,所以這里不用實現(xiàn)任何一個方法也不會報錯。那么如果我想監(jiān)聽動畫結(jié)束這個事件强品,就只需要單獨重寫這一個方法就可以了膘侮,如下所示:
[java]view plaincopy
anim.addListener(newAnimatorListenerAdapter()?{
@Override
public void onAnimationEnd(Animator?animation)?{
}
});
我們可以使用代碼來編寫所有的動畫功能,這也是最常用的一種做法择懂。不過喻喳,過去的補間動畫除了使用代碼編寫之外也是可以使用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編寫動畫在可讀性方面還是挺高的,上面的內(nèi)容相信不用我做解釋大家也都看得懂吧奶赠。
另外鱼填,我們也可以使用XML來完成復雜的組合動畫操作,比如將一個視圖先從屏幕外移動進屏幕毅戈,然后開始旋轉(zhuǎn)360度苹丸,旋轉(zhuǎn)的同時進行淡入淡出操作,就可以這樣寫:
[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文件是編寫好了商模,那么我們?nèi)绾卧诖a中把文件加載進來并將動畫啟動呢?只需調(diào)用如下代碼即可:
[java]view plaincopy
Animator?animator?=?AnimatorInflater.loadAnimator(context,?R.animator.anim_file);
animator.setTarget(view);
animator.start();
調(diào)用AnimatorInflater的loadAnimator來將XML動畫文件加載進來,然后再調(diào)用setTarget()方法將這個動畫設置到某一個對象上面阻桅,最后再調(diào)用start()方法啟動動畫就可以了凉倚,就是這么簡單。
好的嫂沉,通過本篇文章的學習,我相信大家已經(jīng)對屬性動畫的基本用法已經(jīng)有了一個相當不錯的認識扮碧,并把最常用的一些功能都掌握好了趟章,那么本篇文章的內(nèi)容就到這里,下篇文章當中會繼續(xù)介紹屬性動畫,講解ValueAnimator和ObjectAnimator的高級用法,感興趣的朋友請繼續(xù)閱讀Android屬性動畫完全解析(中)钱豁,ValueAnimator和ObjectAnimator的高級用法疤坝。