精品视频日韩无码,伊人久久无码av一区二区三区,久久艹视频国产视频,欧美成A人免费观看久久

  1. <tt id="u23fe"><i id="u23fe"><sub id="u23fe"></sub></i></tt>

      <b id="u23fe"><address id="u23fe"><kbd id="u23fe"></kbd></address></b>

      <source id="u23fe"><track id="u23fe"></track></source>
    1. 位置: 編程技術(shù) - 正文

      Android屬性動(dòng)畫完全解析(上),初識屬性動(dòng)畫的基本用法(android 屬性動(dòng)畫原理)

      編輯:rootadmin

      推薦整理分享Android屬性動(dòng)畫完全解析(上),初識屬性動(dòng)畫的基本用法(android 屬性動(dòng)畫原理),希望有所幫助,僅作參考,歡迎閱讀內(nèi)容。

      文章相關(guān)熱門搜索詞:android的動(dòng)畫類型,Android屬性動(dòng)畫,android 屬性動(dòng)畫上下移動(dòng),android 屬性動(dòng)畫 縮放,android 屬性動(dòng)畫改變view大小,android屬性動(dòng)畫不流暢,android屬性動(dòng)畫平移,Android屬性動(dòng)畫,內(nèi)容如對您有幫助,希望把文章鏈接給更多的朋友!

      轉(zhuǎn)載請注明出處: animation)和補(bǔ)間動(dòng)畫(tweened animation)。逐幀動(dòng)畫的工作原理很簡單,其實(shí)就是將一個(gè)完整的動(dòng)畫拆分成一張張單獨(dú)的圖片,然后再將它們連貫起來進(jìn)行播放,類&#;于動(dòng)畫片的工作原理。補(bǔ)間動(dòng)畫則是可以對View進(jìn)行一系列的動(dòng)畫操作,包括淡入淡出、縮放、平移、旋轉(zhuǎn)四種。

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

      為什么要引入屬性動(dòng)畫?

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

      其實(shí)上面所謂的健全都是相對的,如果你的需求中只需要對View進(jìn)行移動(dòng)、縮放、旋轉(zhuǎn)和淡入淡出操作,那么補(bǔ)間動(dòng)畫確實(shí)已經(jīng)足夠健全了。但是很顯然,這些功能是不足以覆蓋所有的場景的,一旦我們的需求超出了移動(dòng)、縮放、旋轉(zhuǎn)和淡入淡出這四種對View的操作,那么補(bǔ)間動(dòng)畫就不能再幫我們忙了,也就是說它在功能和可擴(kuò)展方面都有相當(dāng)大的局限性,那么下面我們就來看看補(bǔ)間動(dòng)畫所不能勝任的場景。

      注意上面我在介紹補(bǔ)間動(dòng)畫的時(shí)候都有使用“對View進(jìn)行操作”這樣的描述,沒錯(cuò),補(bǔ)間動(dòng)畫是只能夠作用在View上的。也就是說,我們可以對一個(gè)Button、TextView、甚至是LinearLayout、或者其它任何繼承自View的組件進(jìn)行動(dòng)畫操作,但是如果我們想要對一個(gè)非View的對象進(jìn)行動(dòng)畫操作,抱歉,補(bǔ)間動(dòng)畫就幫不上忙了??赡苡械呐笥褧械讲荒芾斫?,我怎么會需要對一個(gè)非View的對象進(jìn)行動(dòng)畫操作呢?這里我舉一個(gè)簡單的例子,比如說我們有一個(gè)自定義的View,在這個(gè)View當(dāng)中有一個(gè)Point對象用于管理坐標(biāo),然后在onDraw()方法當(dāng)中就是根據(jù)這個(gè)Point對象的坐標(biāo)&#;來進(jìn)行繪制的。也就是說,如果我們可以對Point對象進(jìn)行動(dòng)畫操作,那么整個(gè)自定義View的動(dòng)畫效果就有了。顯然,補(bǔ)間動(dòng)畫是不具備這個(gè)功能的,這是它的第一個(gè)缺陷。

      然后補(bǔ)間動(dòng)畫還有一個(gè)缺陷,就是它只能夠?qū)崿F(xiàn)移動(dòng)、縮放、旋轉(zhuǎn)和淡入淡出這四種動(dòng)畫操作,那如果我們希望可以對View的背景色進(jìn)行動(dòng)態(tài)地改變呢?很遺憾,我們只能靠自己去實(shí)現(xiàn)了。說白了,之前的補(bǔ)間動(dòng)畫機(jī)制就是使用硬編碼的方式來完成的,功能限定死就是這些,基本上沒有任何擴(kuò)展性可言。

      最后,補(bǔ)間動(dòng)畫還有一個(gè)致命的缺陷,就是它只是改變了View的顯示效果而已,而不會真正去改變View的屬性。什么意思呢?比如說,現(xiàn)在屏幕的左上角有一個(gè)按鈕,然后我們通過補(bǔ)間動(dòng)畫將它移動(dòng)到了屏幕的右下角,現(xiàn)在你可以去嘗試點(diǎn)擊一下這個(gè)按鈕,點(diǎn)擊事件是絕對不會觸發(fā)的,因?yàn)閷?shí)際上這個(gè)按鈕還是停留在屏幕的左上角,只不過補(bǔ)間動(dòng)畫將這個(gè)按鈕繪制到了屏幕的右下角而已。

      也正是因?yàn)檫@些原因,Android開發(fā)團(tuán)隊(duì)決定在3.0版本當(dāng)中引入屬性動(dòng)畫這個(gè)功能,那么屬性動(dòng)畫是不是就把上述的問題全部解決掉了?下面我們就來一起看一看。

      新引入的屬性動(dòng)畫機(jī)制已經(jīng)不再是針對于View來設(shè)計(jì)的了,也不限定于只能實(shí)現(xiàn)移動(dòng)、縮放、旋轉(zhuǎn)和淡入淡出這幾種動(dòng)畫操作,同時(shí)也不再只是一種視覺上的動(dòng)畫效果了。它實(shí)際上是一種不斷地對&#;進(jìn)行操作的機(jī)制,并將&#;賦&#;到指定對象的指定屬性上,可以是任意對象的任意屬性。所以我們?nèi)匀豢梢詫⒁粋€(gè)View進(jìn)行移動(dòng)或者縮放,但同時(shí)也可以對自定義View中的Point對象進(jìn)行動(dòng)畫操作了。我們只需要告訴系統(tǒng)動(dòng)畫的運(yùn)行時(shí)長,需要執(zhí)行哪種類型的動(dòng)畫,以及動(dòng)畫的初始&#;和結(jié)束&#;,剩下的工作就可以全部交給系統(tǒng)去完成了。

      既然屬性動(dòng)畫的實(shí)現(xiàn)機(jī)制是通過對目標(biāo)對象進(jìn)行賦&#;并修改其屬性來實(shí)現(xiàn)的,那么之前所說的按鈕顯示的問題也就不復(fù)存在了,如果我們通過屬性動(dòng)畫來移動(dòng)一個(gè)按鈕,那么這個(gè)按鈕就是真正的移動(dòng)了,而不再是僅僅在另外一個(gè)位置繪制了而已。

      好了,介紹了這么多,相信大家已經(jīng)對屬性動(dòng)畫有了一個(gè)最基本的認(rèn)識了,下面我們就來開始學(xué)習(xí)一下屬性動(dòng)畫的用法。

      ValueAnimator

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

      但是ValueAnimator的用法卻一點(diǎn)都不復(fù)雜,我們先從最簡單的功能看起吧,比如說想要將一個(gè)&#;從0平滑過渡到1,時(shí)長毫秒,就可以這樣寫:

      [java] view plaincopyValueAnimator anim = ValueAnimator.ofFloat(0f, 1f); anim.setDuration(); anim.start(); 怎么樣?很簡單吧,調(diào)用ValueAnimator的ofFloat()方法就可以構(gòu)建出一個(gè)ValueAnimator的實(shí)例,ofFloat()方法當(dāng)中允許傳入多個(gè)float類型的參數(shù),這里傳入0和1就表示將&#;從0平滑過渡到1,然后調(diào)用ValueAnimator的setDuration()方法來設(shè)置動(dòng)畫運(yùn)行的時(shí)長,最后調(diào)用start()方法啟動(dòng)動(dòng)畫。

      用法就是這么簡單,現(xiàn)在如果你運(yùn)行一下上面的代碼,動(dòng)畫就會執(zhí)行了??墒沁@只是一個(gè)將&#;從0過渡到1的動(dòng)畫,又看不到任何界面效果,我們怎樣才能知道這個(gè)動(dòng)畫是不是已經(jīng)真正運(yùn)行了呢?這就需要借助監(jiān)聽器來實(shí)現(xiàn)了,如下所示:

      [java] view plaincopyValueAnimator anim = ValueAnimator.ofFloat(0f, 1f); anim.setDuration(); anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { float currentValue = (float) animation.getAnimatedValue(); Log.d("TAG", "cuurent value is " &#; currentValue); } }); anim.start(); 可以看到,這里我們通過addUpdateListener()方法來添加一個(gè)動(dòng)畫的監(jiān)聽器,在動(dòng)畫執(zhí)行的過程中會不斷地進(jìn)行回調(diào),我們只需要在回調(diào)方法當(dāng)中將當(dāng)前的&#;取出并打印出來,就可以知道動(dòng)畫有沒有真正運(yùn)行了。運(yùn)行上述代碼,控制臺打印如下所示:

      從打印日志的&#;我們就可以看出,ValueAnimator確實(shí)已經(jīng)在正常工作了,&#;在毫秒的時(shí)間內(nèi)從0平滑過渡到了1,而這個(gè)計(jì)算工作就是由ValueAnimator幫助我們完成的。另外ofFloat()方法當(dāng)中是可以傳入任意多個(gè)參數(shù)的,因此我們還可以構(gòu)建出更加復(fù)雜的動(dòng)畫邏輯,比如說將一個(gè)&#;在5秒內(nèi)從0過渡到5,再過渡到3,再過渡到,就可以這樣寫:

      [java] view plaincopyValueAnimator anim = ValueAnimator.ofFloat(0f, 5f, 3f, f); anim.setDuration(); anim.start(); 當(dāng)然也許你并不需要小數(shù)位數(shù)的動(dòng)畫過渡,可能你只是希望將一個(gè)整數(shù)&#;從0平滑地過渡到,那么也很簡單,只需要調(diào)用ValueAnimator的ofInt()方法就可以了,如下所示:[java] view plaincopyValueAnimator anim = ValueAnimator.ofInt(0, ); ValueAnimator當(dāng)中最常用的應(yīng)該就是ofFloat()和ofInt()這兩個(gè)方法了,另外還有一個(gè)ofObject()方法,我會在下篇文章進(jìn)行講解。

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

      ObjectAnimator

      相比于ValueAnimator,ObjectAnimator可能才是我們最常接觸到的類,因?yàn)閂alueAnimator只不過是對&#;進(jìn)行了一個(gè)平滑的動(dòng)畫過渡,但我們實(shí)際使用到這種功能的場景好像并不多。而ObjectAnimator則就不同了,它是可以直接對任意對象的任意屬性進(jìn)行動(dòng)畫操作的,比如說View的alpha屬性。

      不過雖說ObjectAnimator會更加常用一些,但是它其實(shí)是繼承自ValueAnimator的,底層的動(dòng)畫實(shí)現(xiàn)機(jī)制也是基于ValueAnimator來完成的,因此ValueAnimator仍然是整個(gè)屬性動(dòng)畫當(dāng)中最核心的一個(gè)類。那么既然是繼承關(guān)系,說明ValueAnimator中可以使用的方法在ObjectAnimator中也是可以正常使用的,它們的用法也非常類&#;,這里如果我們想要將一個(gè)TextView在5秒中內(nèi)從常規(guī)變換成全透明,再從全透明變換成常規(guī),就可以這樣寫:

      [java] view plaincopyObjectAnimator animator = ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f, 1f); animator.setDuration(); animator.start(); 可以看到,我們還是調(diào)用了ofFloat()方法來去創(chuàng)建一個(gè)ObjectAnimator的實(shí)例,只不過ofFloat()方法當(dāng)中接收的參數(shù)有點(diǎn)變化了。這里第一個(gè)參數(shù)要求傳入一個(gè)object對象,我們想要對哪個(gè)對象進(jìn)行動(dòng)畫操作就傳入什么,這里我傳入了一個(gè)textview。第二個(gè)參數(shù)是想要對該對象的哪個(gè)屬性進(jìn)行動(dòng)畫操作,由于我們想要改變TextView的不透明度,因此這里傳入"alpha"。后面的參數(shù)就是不固定長度了,想要完成什么樣的動(dòng)畫就傳入什么&#;,這里傳入的&#;就表示將TextView從常規(guī)變換成全透明,再從全透明變換成常規(guī)。之后調(diào)用setDuration()方法來設(shè)置動(dòng)畫的時(shí)長,然后調(diào)用start()方法啟動(dòng)動(dòng)畫,效果如下圖所示:

      學(xué)會了這一個(gè)用法之后,其它的用法我們就可以舉一反三了,那比如說我們想要將TextView進(jìn)行一次度的旋轉(zhuǎn),就可以這樣寫:

      [java] view plaincopyObjectAnimator animator = ObjectAnimator.ofFloat(textview, "rotation", 0f, f); animator.setDuration(); animator.start(); 可以看到,這里我們將第二個(gè)參數(shù)改成了"rotation",然后將動(dòng)畫的初始&#;和結(jié)束&#;分別設(shè)置成0和,現(xiàn)在運(yùn)行一下代碼,效果如下圖所示:

      Android屬性動(dòng)畫完全解析(上),初識屬性動(dòng)畫的基本用法(android 屬性動(dòng)畫原理)

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

      [java] view plaincopyfloat curTranslationX = textview.getTranslationX(); ObjectAnimator animator = ObjectAnimator.ofFloat(textview, "translationX", curTranslationX, -f, curTranslationX); animator.setDuration(); animator.start(); 這里我們先是調(diào)用了TextView的getTranslationX()方法來獲取到當(dāng)前TextView的translationX的位置,然后ofFloat()方法的第二個(gè)參數(shù)傳入"translationX",緊接著后面三個(gè)參數(shù)用于告訴系統(tǒng)TextView應(yīng)該怎么移動(dòng),現(xiàn)在運(yùn)行一下代碼,效果如下圖所示:

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

      [java] view plaincopyObjectAnimator animator = ObjectAnimator.ofFloat(textview, "scaleY", 1f, 3f, 1f); animator.setDuration(); animator.start(); 這里將ofFloat()方法的第二個(gè)參數(shù)改成了"scaleY",表示在垂直方向上進(jìn)行縮放,現(xiàn)在重新運(yùn)行一下程序,效果如下圖所示:

      到目前為止,ObjectAnimator的用法還算是相當(dāng)簡單吧,但是我相信肯定會有不少朋友現(xiàn)在心里都有同樣一個(gè)疑問,就是ofFloat()方法的第二個(gè)參數(shù)到底可以傳哪些&#;呢?目前我們使用過了alpha、rotation、translationX和scaleY這幾個(gè)&#;,分別可以完成淡入淡出、旋轉(zhuǎn)、水平移動(dòng)、垂直縮放這幾種動(dòng)畫,那么還有哪些&#;是可以使用的呢?其實(shí)這個(gè)問題的答案非常玄乎,就是我們可以傳入任意的&#;到ofFloat()方法的第二個(gè)參數(shù)當(dāng)中。任意的&#;?相信這很出乎大家的意料吧,但事實(shí)就是如此。因?yàn)镺bjectAnimator在設(shè)計(jì)的時(shí)候就沒有針對于View來進(jìn)行設(shè)計(jì),而是針對于任意對象的,它所負(fù)責(zé)的工作就是不斷地向某個(gè)對象中的某個(gè)屬性進(jìn)行賦&#;,然后對象根據(jù)屬性&#;的改變再來決定如何展現(xiàn)出來。

      那么比如說我們調(diào)用下面這樣一段代碼:

      [java] view plaincopyObjectAnimator.ofFloat(textview, "alpha", 1f, 0f); 其實(shí)這段代碼的意思就是ObjectAnimator會幫我們不斷地改變textview對象中alpha屬性的&#;,從1f變化到0f。然后textview對象需要根據(jù)alpha屬性&#;的改變來不斷刷新界面的顯示,從而讓用戶可以看出淡入淡出的動(dòng)畫效果。

      那么textview對象中是不是有alpha屬性這個(gè)&#;呢?沒有,不僅textview沒有這個(gè)屬性,連它所有的父類也是沒有這個(gè)屬性的!這就奇怪了,textview當(dāng)中并沒有alpha這個(gè)屬性,ObjectAnimator是如何進(jìn)行操作的呢?其實(shí)ObjectAnimator內(nèi)部的工作機(jī)制并不是直接對我們傳入的屬性名進(jìn)行操作的,而是會去尋找這個(gè)屬性名對應(yīng)的get和set方法,因此alpha屬性所對應(yīng)的get和set方法應(yīng)該就是:

      [java] view plaincopypublic void setAlpha(float value); public float getAlpha(); 那么textview對象中是否有這兩個(gè)方法呢?確實(shí)有,并且這兩個(gè)方法是由View對象提供的,也就是說不僅TextView可以使用這個(gè)屬性來進(jìn)行淡入淡出動(dòng)畫操作,任何繼承自View的對象都可以的。

      既然alpha是這個(gè)樣子,相信大家一定已經(jīng)明白了,前面我們所用的所有屬性都是這個(gè)工作原理,那么View當(dāng)中一定也存在著setRotation()、getRotation()、setTranslationX()、getTranslationX()、setScaleY()、getScaleY()這些方法,不信的話你可以到View當(dāng)中去找一下。

      組合動(dòng)畫

      獨(dú)立的動(dòng)畫能夠?qū)崿F(xiàn)的視覺效果畢竟是相當(dāng)有限的,因此將多個(gè)動(dòng)畫組合到一起播放就顯得尤為重要。幸運(yùn)的是,Android團(tuán)隊(duì)在設(shè)計(jì)屬性動(dòng)畫的時(shí)候也充分考慮到了組合動(dòng)畫的功能,因此提供了一套非常豐富的API來讓我們將多個(gè)動(dòng)畫組合到一起。

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

      after(Animator anim) 將現(xiàn)有動(dòng)畫插入到傳入的動(dòng)畫之后執(zhí)行after(long delay) 將現(xiàn)有動(dòng)畫延遲指定毫秒后執(zhí)行before(Animator anim) 將現(xiàn)有動(dòng)畫插入到傳入的動(dòng)畫之前執(zhí)行with(Animator anim) 將現(xiàn)有動(dòng)畫和傳入的動(dòng)畫同時(shí)執(zhí)行

      好的,有了這四個(gè)方法,我們就可以完成組合動(dòng)畫的邏輯了,那么比如說我們想要讓TextView先從屏幕外移動(dòng)進(jìn)屏幕,然后開始旋轉(zhuǎn)度,旋轉(zhuǎn)的同時(shí)進(jìn)行淡入淡出操作,就可以這樣寫:

      [java] view plaincopyObjectAnimator moveIn = ObjectAnimator.ofFloat(textview, "translationX", -f, 0f); ObjectAnimator rotate = ObjectAnimator.ofFloat(textview, "rotation", 0f, f); ObjectAnimator fadeInOut = ObjectAnimator.ofFloat(textview, "alpha", 1f, 0f, 1f); AnimatorSet animSet = new AnimatorSet(); animSet.play(rotate).with(fadeInOut).after(moveIn); animSet.setDuration(); animSet.start(); 可以看到,這里我們先是把三個(gè)動(dòng)畫的對象全部創(chuàng)建出來,然后new出一個(gè)AnimatorSet對象之后將這三個(gè)動(dòng)畫對象進(jìn)行播放排序,讓旋轉(zhuǎn)和淡入淡出動(dòng)畫同時(shí)進(jìn)行,并把它們插入到了平移動(dòng)畫的后面,最后是設(shè)置動(dòng)畫時(shí)長以及啟動(dòng)動(dòng)畫。運(yùn)行一下上述代碼,效果如下圖所示:

      Animator監(jiān)聽器

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

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

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

      [java] view plaincopyanim.addListener(new AnimatorListener() { @Override public void onAnimationStart(Animator animation) { } @Override public void onAnimationRepeat(Animator animation) { } @Override public void onAnimationEnd(Animator animation) { } @Override public void onAnimationCancel(Animator animation) { } }); 可以看到,我們需要實(shí)現(xiàn)接口中的四個(gè)方法,onAnimationStart()方法會在動(dòng)畫開始的時(shí)候調(diào)用,onAnimationRepeat()方法會在動(dòng)畫重復(fù)執(zhí)行的時(shí)候調(diào)用,onAnimationEnd()方法會在動(dòng)畫結(jié)束的時(shí)候調(diào)用,onAnimationCancel()方法會在動(dòng)畫被取消的時(shí)候調(diào)用。

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

      [java] view plaincopyanim.addListener(new AnimatorListenerAdapter() { }); 這里我們向addListener()方法中傳入這個(gè)適配器對象,由于AnimatorListenerAdapter中已經(jīng)將每個(gè)接口都實(shí)現(xiàn)好了,所以這里不用實(shí)現(xiàn)任何一個(gè)方法也不會報(bào)錯(cuò)。那么如果我想監(jiān)聽動(dòng)畫結(jié)束這個(gè)事件,就只需要單獨(dú)重寫這一個(gè)方法就可以了,如下所示:[java] view plaincopyanim.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { } }); 使用XML編寫動(dòng)畫

      我們可以使用代碼來編寫所有的動(dòng)畫功能,這也是最常用的一種做法。不過,過去的補(bǔ)間動(dòng)畫除了使用代碼編寫之外也是可以使用XML編寫的,因此屬性動(dòng)畫也提供了這一功能,即通過XML來完成和代碼一樣的屬性動(dòng)畫功能。

      通過XML來編寫動(dòng)畫可能會比通過代碼來編寫動(dòng)畫要慢一些,但是在重用方面將會變得非常輕松,比如某個(gè)將通用的動(dòng)畫編寫到XML里面,我們就可以在各個(gè)界面當(dāng)中輕松去重用它。

      如果想要使用XML來編寫動(dòng)畫,首先要在res目錄下面新建一個(gè)animator文件夾,所有屬性動(dòng)畫的XML文件都應(yīng)該存放在這個(gè)文件夾當(dāng)中。然后在XML文件中我們一共可以使用如下三種標(biāo)簽:

      <animator> 對應(yīng)代碼中的ValueAnimator<objectAnimator> 對應(yīng)代碼中的ObjectAnimator<set> 對應(yīng)代碼中的AnimatorSet

      那么比如說我們想要實(shí)現(xiàn)一個(gè)從0到平滑過渡的動(dòng)畫,在XML當(dāng)中就可以這樣寫:

      [html] view plaincopy<animator xmlns:android=" android:valueFrom="0" android:valueTo="" android:valueType="intType"/> 而如果我們想將一個(gè)視圖的alpha屬性從1變成0,就可以這樣寫:[html] view plaincopy<objectAnimator xmlns:android=" android:valueFrom="1" android:valueTo="0" android:valueType="floatType" android:propertyName="alpha"/> 其實(shí)XML編寫動(dòng)畫在可讀性方面還是挺高的,上面的內(nèi)容相信不用我做解釋大家也都看得懂吧。

      另外,我們也可以使用XML來完成復(fù)雜的組合動(dòng)畫操作,比如將一個(gè)視圖先從屏幕外移動(dòng)進(jìn)屏幕,然后開始旋轉(zhuǎn)度,旋轉(zhuǎn)的同時(shí)進(jìn)行淡入淡出操作,就可以這樣寫:

      [html] view plaincopy<set xmlns:android=" android:ordering="sequentially" > <objectAnimator android:duration="" android:propertyName="translationX" android:valueFrom="-" android:valueTo="0" android:valueType="floatType" > </objectAnimator> <set android:ordering="together" > <objectAnimator android:duration="" android:propertyName="rotation" android:valueFrom="0" android:valueTo="" android:valueType="floatType" > </objectAnimator> <set android:ordering="sequentially" > <objectAnimator android:duration="" android:propertyName="alpha" android:valueFrom="1" android:valueTo="0" android:valueType="floatType" > </objectAnimator> <objectAnimator android:duration="" android:propertyName="alpha" android:valueFrom="0" android:valueTo="1" android:valueType="floatType" > </objectAnimator> </set> </set> </set> 這段XML實(shí)現(xiàn)的效果和我們剛才通過代碼來實(shí)現(xiàn)的組合動(dòng)畫的效果是一模一樣的,每個(gè)參數(shù)的含義都非常清楚,相信大家都是一看就懂,我就不再一一解釋了。

      最后XML文件是編寫好了,那么我們?nèi)绾卧诖a中把文件加載進(jìn)來并將動(dòng)畫啟動(dòng)呢?只需調(diào)用如下代碼即可:

      [java] view plaincopyAnimator animator = AnimatorInflater.loadAnimator(context, R.animator.anim_file); animator.setTarget(view); animator.start(); 調(diào)用AnimatorInflater的loadAnimator來將XML動(dòng)畫文件加載進(jìn)來,然后再調(diào)用setTarget()方法將這個(gè)動(dòng)畫設(shè)置到某一個(gè)對象上面,最后再調(diào)用start()方法啟動(dòng)動(dòng)畫就可以了,就是這么簡單。

      好的,通過本篇文章的學(xué)習(xí),我相信大家已經(jīng)對屬性動(dòng)畫的基本用法已經(jīng)有了一個(gè)相當(dāng)不錯(cuò)的認(rèn)識,并把最常用的一些功能都掌握好了,那么本篇文章的內(nèi)容就到這里,下篇文章當(dāng)中會繼續(xù)介紹屬性動(dòng)畫,講解ValueAnimator和ObjectAnimator的高級用法,感興趣的朋友請繼續(xù)閱讀 Android屬性動(dòng)畫完全解析(中),ValueAnimator和ObjectAnimator的高級用法 。

      開源項(xiàng)目源碼解析-xUtils 源碼解析 xUtils源碼解析本文為Android開源項(xiàng)目源碼解析中xUtils部分。項(xiàng)目地址:xUtils,分析的版本:c2ac,Demo地址:xUtilsDemo分析者:Caij,校對者:maogy,校對

      掌握Activity 的生命周期(Lifecycle) Activity的生命周期(Lifecycle)在用戶與App進(jìn)行交互,開啟APP,退出APP,按Home鍵回到桌面等等的時(shí)候,相關(guān)的Activity實(shí)例將會不斷的切換Activity生命周期中

      android開發(fā)之單點(diǎn)觸摸 相對于多點(diǎn)觸摸,單點(diǎn)觸摸還是很簡單的。新建一個(gè)工程,先看看布局文件:RelativeLayoutxmlns:android="

      標(biāo)簽: android 屬性動(dòng)畫原理

      本文鏈接地址:http://esstyw.cn/biancheng/382242.html 轉(zhuǎn)載請保留說明!

      上一篇:Fragment嵌套時(shí)注意點(diǎn)(fragment里面如何嵌套fragment)

      下一篇:開源項(xiàng)目源碼解析-xUtils 源碼解析(開源項(xiàng)目怎么做)

    2. 跨年度的租金收入如何入賬
    3. 如何在網(wǎng)上查詢個(gè)人房產(chǎn)
    4. 暫估入庫可以跨年嗎
    5. 免征增值稅項(xiàng)目記憶
    6. 投資性房地產(chǎn)轉(zhuǎn)固定資產(chǎn)賬務(wù)處理
    7. 承兌匯票轉(zhuǎn)出
    8. 下列應(yīng)稅項(xiàng)目中,不按次計(jì)算征收個(gè)人所得稅的是
    9. 年終獎(jiǎng)社保怎么算
    10. 短期借款的會計(jì)科目
    11. 重慶個(gè)人住房房產(chǎn)稅申報(bào)
    12. 企業(yè)業(yè)務(wù)招待費(fèi)標(biāo)準(zhǔn)規(guī)定
    13. 本年利潤的借貸雙方表示什么
    14. 生產(chǎn)的廢料怎么做賬
    15. win10怎么建立多個(gè)用戶
    16. 在windows 7中
    17. 支付借款利息怎么做賬
    18. 用系統(tǒng)自帶命令行安裝WIN10
    19. yoosee怎么安裝
    20. 其他應(yīng)付款與應(yīng)付款的區(qū)別
    21. 路由器的默認(rèn)網(wǎng)關(guān)在哪里看
    22. 蝴蝶蘭的養(yǎng)殖方法和注意事項(xiàng) 盆栽蝴蝶蘭爛根
    23. 壞賬準(zhǔn)備 結(jié)轉(zhuǎn)
    24. 違反發(fā)票管理的處罰
    25. 律師異地辦案家屬要跟著嗎
    26. php獲取手機(jī)型號
    27. 搭建小技巧
    28. gpt3 api
    29. 戶外電源需要要充電嗎
    30. php創(chuàng)建多級目錄的方法
    31. 銷售原材料怎么入賬
    32. bulkload命令
    33. 企業(yè)收到企業(yè)借款需要交稅
    34. 對公賬戶的資金怎么轉(zhuǎn)出
    35. 一般納稅人開發(fā)票給小規(guī)模納稅人
    36. 物業(yè)公司代收水費(fèi)賬務(wù)處理
    37. 可供出售金融資產(chǎn)新準(zhǔn)則叫什么
    38. 新個(gè)稅累計(jì)預(yù)扣怎么算
    39. mysql5.7.33壓縮包安裝教程
    40. 消費(fèi)稅計(jì)算的三種形式
    41. 零售行業(yè)bi
    42. 以前年度虧損要調(diào)整嗎
    43. 建筑企業(yè)預(yù)繳的增值稅怎么抵扣
    44. 預(yù)繳所得稅年底處理賬務(wù)嗎
    45. 個(gè)稅申報(bào)當(dāng)月申報(bào)了上月應(yīng)發(fā)工資怎么調(diào)整
    46. 科目余額表平是什么情況
    47. 如何收信用卡付款
    48. 廣告公司收到廣告收入會計(jì)分錄
    49. 村集體經(jīng)濟(jì)組織的銀行存款可以向外單位或個(gè)人出租出借
    50. 銷售返利怎么做稅務(wù)處理
    51. 固定資產(chǎn)租賃費(fèi)評估
    52. 研發(fā)費(fèi)用資本化條件
    53. 個(gè)體工商怎么申報(bào)
    54. 個(gè)稅抵扣項(xiàng)目是什么
    55. 私營企業(yè)固定資產(chǎn)法律制度
    56. linux實(shí)現(xiàn)mysql數(shù)據(jù)庫每天自動(dòng)備份定時(shí)備份
    57. win10如何固定桌面圖標(biāo)
    58. 怎么恢復(fù)Windows xp藍(lán)天白云壁紙
    59. 老舊的詩琴五個(gè)琴譜大全
    60. windowsxp優(yōu)點(diǎn)
    61. inc是什么軟件
    62. onionwormimmune.exe是什么
    63. linux必學(xué)的60個(gè)命令及使用
    64. win7怎么截屏幕
    65. win10商店沒有圖標(biāo)
    66. unity讀取文本文件
    67. excel初始化時(shí)出錯(cuò)
    68. linux shell腳本編程入門
    69. 利用python進(jìn)行爬蟲
    70. WinForm中UnityWebPlayer屏蔽右鍵菜單
    71. nodejs事件隊(duì)列
    72. 細(xì)說java
    73. jquery .html的用法
    74. python搜索功能
    75. jquery實(shí)現(xiàn)下拉菜單
    76. 總結(jié)網(wǎng)絡(luò)io模型的特點(diǎn)
    77. 建筑垃圾清運(yùn)屬于什么應(yīng)稅服務(wù)
    78. 黑龍江省稅務(wù)局領(lǐng)導(dǎo)最新分工
    79. 豐臺和朝陽中間是哪里
    80. 廣西殘疾人保障金比例
    81. 稅收優(yōu)惠政策能調(diào)動(dòng)公眾的捐贈(zèng)積極性
    82. 免責(zé)聲明:網(wǎng)站部分圖片文字素材來源于網(wǎng)絡(luò),如有侵權(quán),請及時(shí)告知,我們會第一時(shí)間刪除,謝謝! 郵箱:opceo@qq.com

      鄂ICP備2023003026號

      網(wǎng)站地圖: 企業(yè)信息 工商信息 財(cái)稅知識 網(wǎng)絡(luò)常識 編程技術(shù)

      友情鏈接: 武漢網(wǎng)站建設(shè)