Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android動畫3-屬性動畫(PropertyAnimation)

Android動畫3-屬性動畫(PropertyAnimation)

編輯:關於Android編程

屬性動畫是為了彌補之前兩種動畫模式的不足之處產生的(Android3.0之後才有的),特點是 真實對view的屬性進行改動,並且能支持自定義屬性動畫, 基本上能實現所有能想到的動畫。   屬性動畫是通過不斷對view的屬性調用set和get方法,然後重繪在界面上來達到“動畫”的效果。   大綱: 1. PropertyAnimation簡單使用 2. ValueAnimator高級用法 3. ObjectAnimator高級用法 4. LayoutAnimations布局動畫 5. ViewPropertyAnimator使用方法 6. 總結   一 PropertyAnimation簡單使用 1. 使用ValueAnimator ValueAnimator這個類是實現屬性動畫的核心類,屬性動畫是通過不斷的對目標屬性的值進行修改直到等於結束值來完成的,這個類內部就會計算每一次的修改值。我們只要傳入 起點值,終點值和動畫總時長,這個類能計算出 起點到終點 平滑過渡的每一個點的屬性值。 使用這個類實現屬性動畫我們要重點關注一下幾個方法: 1. of系列方法-動畫創建方法 ValueAnimatorofFloat(float... values) ValueAnimatorofArgb(int... values) ValueAnimator ofInt(int... values) ValueAnimatorofObject(TypeEvaluator evaluator, Object... values) ValueAnimatorofPropertyValuesHolder(PropertyValuesHolder... values) of系列方法就是用來創建ValueAnimator的方法,使用哪個方法取決於你想使屬性怎樣變化,如從0.1到23.5,中間值可以是小數這時選用ofFloat(),如從1到23中間都必須是整數就用ofInt(),如果是自定義對象,就要傳入一個估值器(Evaluator,之後會說)。 2. set系列方法-動畫參數設置方法 setDuration() 動畫時長 setEvaluator() 設置估值器 setInterpolator() 設置插值器 setRepeatCount() 設置重復次數 setRepeatMode() 設置重復模式 Animation.RESTART-從動畫起始位置再重復動畫一次 Animation.REVERSE-從當前動畫結束位置倒著重復一次 setStartDelay() 設置動畫延遲時間 3. 動畫控制方法&其他方法 cancel() 取消動畫 終止當前動畫的進度 end() 結束動畫 將動畫狀態跳到終點值(例如:從0到1的過程中,當值變為0.5時,調cancel()最後一個值就是0.5,調end()最後一個值是1,倒數第二個值是0.5) isRunning() 返回當前動畫執行狀態, true-正在執行 isStarted() 返回動畫是否執行 true-已經執行 pause() 暫停動畫 resume() 恢復暫停的動畫 reverse() 從當前進度倒著執行 直到到達 起點/終點 start() 開始動畫 舉幾個例子: 1.創建一個實例,添加監聽器,打印數值的變化過程。數值的計算次數和線程的計算壓力大小有關,當當前線程空閒時,計算次數就會比較多,繁忙時,會跳幀,跳過的幀就不會計算了。 \\ 2. 創建一個實例,使用更多的參數 \ of系列方法參數中,關於值的參數都是可變長參數。 傳入1個參數,則視為從當前狀態變化到參數的狀態。傳入2個參數,則以第一個參數為起始點,其二個參數為終點。傳入更多參數,則第一個參數為起始點,最後一個為終點,中間的點都會一個一個達到(類似於折線圖)。這例變化情況為0-->10-->3-->9-->12。 3. 創建一個實例,使用ofInt,並打印數值變化過程 \\ 過程 0-->10-->5,這裡0,9,6重復出現是因為使用的是ofInt()方法,會對小數自動取整   2. 使用ObjectAnimator   ValueAnimator能計算出來這些屬性值,但是貌似和動畫沒什麼關系(其實要使用ValueAnimator直接實現動畫也是可以的,不過比較麻煩),有一種更經常使用的方法來創建動畫,就是使用ValueAnimator的子類ObjectAnimator。 ObjectAnimator繼承自ValueAnimator,即上述的方法ObjectAnimator都可以使用,不同的是ObjectAnimator使用of系列方法的參數有所變化,並且這個類提供了特別多的of方法供傳遞不同的參數,在這裡就先說幾個常用的比較簡單的of方法。 of系列方法: ofArgb(Object target, String PropertyName, int... values) ofInt(Object target, String PropertyName, int... values) ofFloat(Object target, String PropertyName, float... values) ofObject(Object target, String PropertyName, TypeEvaluator evaluator, Object... values) ofPropertyValuesHolder(Object target, String PropertyName, PropertyValuesHolder... values) 這些of方法和ValueAnimator類的of系列方法區別就在於多了前兩個參數,第一個參數是想要執行動畫的view實例,第二個參數是屬性動畫想要更改view的屬性的名稱字符串。 下面舉幾個例子看一下這個類的使用。 舉幾個例子: 1. \\ 這段代碼是將給tv2設置一個動畫,在5s內將其透明度從1-->0-->1。關注ofFloat()方法參數:第一個參數是 想要 實現動畫的 view,第二個參數是想更改的屬性名稱字符串,後面幾個參數是代表變化數值的可變長參數。 2. \\ 這段代碼是將tv2繞中心從0度開始旋轉360度。關注ofFloat()方法:第一個參數是想要實現動畫的view,第二個參數是想要更改的view的屬性名稱字符串,後面幾個是代表變化數值的可變長參數。 3. \\ 這段代碼是把tv2從當前位置水平位移到X坐標為-500的位置然後又移回來。關注ofFloat()方法:第一個參數是想要實現動畫的view,第二個參數是想要更改view的屬性名稱的字符串,後面幾個是代表變化的可變長參數。 4. \\ 這段代碼把tv2按照Y軸方向拉伸到2倍然後還原。關注ofFloat()方法:第一個參數是想要實現動畫的view,第二個參數是想要更改view的屬性名稱的字符串,後面幾個是代表變化的可變長參數。   經過這幾個例子,我們會發現,這種設置動畫的方式非常簡單,主要是對ofFloat()方法的使用,其他方法的使用其實和補間動畫有相似之處。   還有一個問題是,這些of方法的第二個參數到底能傳什麼值,現在我們已經嘗試了alpha,rotation,translationX這三個字符串實現了透明度/旋轉/平移動畫,到底還能傳入什麼值呢?這些of方法的第二個參數能傳入的值是任意的,前提是傳入的屬性名稱要有對應的get/set方法,因為屬性動畫是通過不斷調用一個屬性的get/set方法來對其值進行更改,然後在界面上重繪view完成的,故如果一個屬性沒有get/set方法肯定是不能使用屬性動畫對此屬性進行動畫操作的。反過來講,只要一個屬性有對應的get/set方法,那麼就可以使用屬性動畫的方式對其屬性進行動畫操作。 例: 在view類中, alpha \ 透明度改變 \ rotation\ 旋轉 \ translationX\ X軸方向平移 translationY-Y軸方向平移 \ scaleX\ X軸方向縮放 scaleX-X軸方向縮放 \ 補充: 你可能已經發現了,當時旋轉和縮放可以設置中心點,而ValueAnimator和ObjectAnimator都沒有提供設置中心點的方法,此時,我們就要調用view.setPivotX和view.setPivotY設置中心點。   3. 使用組合動畫 我們在定義補間動畫的時候就使用過AnimationSet來讓多個動畫效果同時執行,現在屬性動畫怎麼達到這種效果呢? Android提供了AnimatorSet類來完成組合動畫的定義。 實現方法: 1. 定義多個屬性動畫 2. 定義AnimatorSet 3. 調用AnimatorSet的一些方法組合動畫 4. 調用AnimatorSet的一些方法設置動畫的一些參數 5. 調用AnimatorSet.start()方法開始動畫   AnimatorSet類直接繼承自ValueAnimator類,和ObjectAnimator類同級。 AnimatorSet類主要方法: play系列: playTogether(Animator... items) 同時執行傳入的動畫 playTogether(Collection items) 同時執行傳入的動畫 playSequentially(Animator... items) 順序執行傳入的動畫(寫在前面就先執行) playSequentially(List items) 順序執行傳入的動畫(寫在前面就先執行) play() 這個方法是重中之重,這個方法會返回一個AnimatorSet.Builder對象,這個對象有四個方法,分別是: with(Animator anim) 將現有動畫和傳入的動畫同時執行 before(Animator anim) 將現有動畫插入到傳入的動畫之前執行 after(Animator anim) 將現有動畫插入到傳入的動畫之後執行 after(long delayMills) 將現有動畫延遲指定毫秒後執行 注:這四個方法都會返回Builder對象,即這四個方法可以連著使用。 舉個例子: \\   4. 使用Animator監聽器 Animator類提供了一個addListener()方法,傳入相應的監聽器就行了。 使用1: \ 使用2:如果只想重寫這些監聽方法裡的一個或者兩個,可以使用new AnimatorListenerAdapter,這個類繼承AnimatorListener,是個抽象類,已經實現了這些監聽方法,new這個,你只需要重寫自己需要的監聽方法就行了,不需要每個方法都實現。 \\ 可以看到你只需要重寫想要的方法即可,並且該類多提供了兩個方法,分別是監聽 動畫暫停時(Pause)和 動畫重新開始時(Resume)。   5. 使用XML定義屬性動畫 1. 在Res目錄下創建animator文件夾 \ 2. 在xml文件中定義屬性動畫 可以看到,xml下有三種標簽可以用: \ 分別對應:\ \ 舉例: \\ 將一個view的alpha從1變成0   \ 實現各種組合動畫,標簽下的 ordering 屬性設置為 together就是同時播放動畫, sequentially就是順序執行動畫。   3. 在代碼中實現屬性動畫 \\ setTarget()方法就是用來設置 實現動畫的view的。 最後調用start方法開始動畫就OK了。     二 ValueAnimator的高級用法   之前已經簡單說過ValueAnimator可以實現對 值 的“動畫操作”(將值從初始值變道最終值),這個類究竟是怎麼做到的呢?這是後就要說一下TypeEvaluator(估值器)。 TypeEvaluator是android.animator包下的一個接口,其已經實現的子類有ArgbEvaluator,FloatEvaluator,IntEvaluator,RectEvaluator。每次我們調用ValueAnimator的of系列方法的時候就會間接調用相應的Evaluator,當調用of方法的時候內部會先計算出來應該確定在哪些時間點計算屬性值(重繪view),然後根據這些時間點對應的進度計算 值 的相關屬性值,Evaluator就是用來根據進度計算值的。 FloatEvaluator源碼: \\ 由源碼可以看出,計算方法是: 起點數值+ 要變化的數值*當前進度 IntEvaluator源碼: \\ 由源碼可以看出,計算方法和Float一樣。   看過這兩個類的源碼,基本能看出來,寫一個類實現TypeEvaluator接口,我們就能自定義估值器,而估值器決定了某一時間點(進度)的計算值,也就是說我們可以自由定義 值 的變化曲線(view的變化曲線)。進一步我們可以自定義值的修改方法來使ValueAnimator可以對任意對象進行“動畫操作”。 (這和Interpolator剛好相反,Interpolator是通過修改當前時間點(進度)的應該顯示的時間點來改變 值(view) 的變化曲線,而估值器是通過對當前時間點(進度)的 值 進行修改來達到目標。)   舉例: 自定義Evaluator使ValueAnimator對自定義bean進行“動畫操作”。 1. 自定義bean \ 定義了 x y z 三個變量,並添加全參構造和get/set(get/set非常重要,屬性動畫就是對get/set進行操作的!),為了顯示結果,我重寫了toString()方法,但是這個不必要,所以沒有在代碼中展示。 2. 自定義Evaluator \\ 簡單起見我也使用了 系統定義的計算方法。 你可以實現更復雜的方法,例如:x坐標按比例變化,y坐標按自由落體公式變化,這就是一個拋物線。 3. 使用ValueAnimator.ofObject()方法 \ 4. 結果: \   這樣就實現了 任意 對象 值的 “動畫”操作。還可以進一步,如果我們將上述這些代碼放在一個自定義View中使用,並且讓view繪制的圖形和坐標有關系,那麼坐標不斷變化,view就是真的在進行“動畫”。這個例子寫法很簡單,比如以x/y坐標畫個圓形/矩形,那麼x/y變化的時候,矩形也就跟著跑了,代碼就不寫了。   這就是 ValueAnimator 的高級用法 ---- 自定義 對象 的動畫操作(自定義view的運動曲線)。     三 ObjectAnimator的高級用法   經過上面對ValueAnimator高級用法的解釋,可能你也想到了,ValueAnimator可以對 值 的變化曲線做自定義處理,到了ObjectAnimator這裡那肯定就是對 要變化 的屬性 進行自定義處理了。(貌似沒什麼關系。。。)   先看下系統提供的對顏色屬性改變的方法: \\ 這裡的屬性名稱參數 必須 填寫 backgroundColor ,填寫color沒有效果(因為此時測試用的view是TextView,該類沒有提供直接操作color屬性的方法,對背景顏色修改要使用backgroundColor)。   此時我就是想要在屬性名稱參數這裡填 color 該怎麼處理? 此時就要用到ObjectAnimator的高級用法了。 舉例: 1. 寫個自定義View,繼承TextView(TextView裡面沒有對color操作的方法,故需要自己寫一個) \ 貼上源碼,重點是 color屬性的set/get方法,set方法中我把顏色設置給畫筆,然後重繪view。即當動畫執行的時候,不斷調用set方法給畫筆設置顏色然後重繪view。 2. 調用ofArgb()方法,此時我使用的是 系統提供的計算顏色變化的估值器 \ 這是系統提供的計算顏色變化的估值器源碼。 然後我調用ofArgb()方法 \\ 此時,我傳入的屬性名稱參數就是 color 了,並且可以看出 可以生效。 如果是自定義的估值器,需要調用ofObject()方法: \,估值器就是你自己寫的計算方法了。這裡我偷個懶,調用系統的估值器計算顏色變化。   這就是 對 自定義屬性 進行 動畫操作的過程。 1. 對自定義屬性設置set/get方法 2. 對自定義屬性的變化函數進行設置,即估值器 3. 使用ofObject方法,然後設置動畫的一些參數(時間之類的),最後start()即可   以上就是ObjectAnimator的高級用法 ---- 對 自定義屬性 進行動畫操作。   四 LayoutAnimations布局動畫(這段大部分復制hongyang大神的。)   布局動畫是用來對一個ViewGroup控件添加/取消childView的過程設置的動畫。 總共提供了四種方式:

LayoutTransition.APPEARING 當一個View在ViewGroup中出現時,對此View設置的動畫

LayoutTransition.CHANGE_APPEARING當一個View在ViewGroup中出現時,對此View對其他View位置造成影響,對其他View設置的動畫

LayoutTransition.DISAPPEARING當一個View在ViewGroup中消失時,對此View設置的動畫

LayoutTransition.CHANGE_DISAPPEARING當一個View在ViewGroup中消失時,對此View對其他View位置造成影響,對其他View設置的動畫

舉例說明:

\

\

\\

重點是LayoutTransition對象,我們是使用了該對象的setAnimator方法,這個方法第一個參數是動畫類型,傳入的參數就是上面說的四種類型;第二個參數就是動畫對象。 這樣的代碼就實現了 給 GridLayout 布局添加childView時候的動畫效果。 這樣的效果是官方默認的,我們可以通過下面的方法自定義動畫效果。 \\ 設置添加childView的動畫為X軸縮放,從0到1。 \   五ViewPropertyAnimator使用方法 ViewPropertyAnimator類是在Android3.1引進來的,為了簡化屬性動畫的定義語法。該類繼承自android.View類。3.1版本之後View類增加了一個方法animate()。 animate()方法可以返回一個ViewPropertyAnimator對象,我們來看一下這個類裡面提供了哪些方法吧。 ViewPropertyAnimator類方法: (方法都很簡單,就不一個一個細細說明了。畢竟是為了簡化語法嘛。) \ \\\\\\\\\ \ 使用這些方法非常簡單。 舉例: 1. tv2 移動到點(500, 500) \\ 2.tv2 移動到點(500, 500),設置時長為5s \\ 3.tv2 移動到點(500, 500),設置時長為5s,設置插值器為反彈插值器 \\ 4.tv2 移動到點(500, 500),設置時長為5s,設置插值器為反彈插值器,同時設置透明度改變。 \ 5. 在4的基礎上,設置縮放動畫 \\ 結果為: \ 這些方法已經可以實現簡單的 平移、縮放、透明度、旋轉 動畫了。 這個類中還有其他方法,但是這畢竟是為了簡化語法,語法簡化了功能當然就簡單了,我覺得不必過於糾結這個類的每一個方法到底什麼用,當實現簡單動畫的時候想起來用一下這些常用方法就行了,如果這些常用方法不行,那就直接用常規寫法。     小結:1. 調用這些方法的入口是 調用 view.animate() 方法。 2. 除了start()/cancel()方法其他方法都會返回一個ViewPropertyAnimator,這個當然就是為了可以寫出連綴語句。 3. 這個類返回ViewPropertyAnimator對象的方法內部都會自己調用start()方法啟動動畫,所以可以不手動調用start()方法。     六 總結   屬性動畫的運行過程: ValueAnimator/ObjectAnimator ----> TimeInterpolator ----> TypeEvaluator ----> setXXX() ----> onDraw() 先調用of系列方法-->通過插值器計算時間節點-->計算相應時間節點的屬性值 --> 給對應屬性賦新值--> 重繪view  
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved