原文 2011-05-30 Introducing ViewPropertyAnimator 發表於 2011.05(和 3.1 發佈的時間同步),做者是 Chet Haase,一個致力於圖形和動畫研究的 Android 開發者,能夠從他的 我的博客graphics-geek.blogspot.com 閱讀更多相關主題的博文。html
譯者說:
這篇文章介紹了在 3.1 中增長的和動畫機制有關的類ViewPropertyAnimator
。先從三個方面作了論述,雖然 3.0 時已經有了能實現任意對象和屬性動畫的 ObjectAnimator,但仍然有必要提供一個新類,以提供一種更加簡明易讀的方式來實現 View 多個屬性的並發動畫。而後介紹了這個新類 ViewPropertyAnimator 的用法。而且提供了一個例子和視頻來展現實際的效果。java本文非全文翻譯,亦非逐字逐句翻譯。android
相關文章:git
如何學習 Android Animation?github
「譯」Android Animation in Honeycomb by Chet Haase(Android 3.0系統中的動畫機制)api
weiyi.li li2.me 2016-02-02 ~ 2016-02-03併發
早先一篇文章「Animation in Honeycomb」(原文連接、譯文連接)介紹了 3.0 增長的 APIs android.animation
,它比之前更容易實現對象動畫和屬性動畫,包括 View.class
在3.0中新增的幾個屬性。爲了使 View 的這幾個新增屬性作動畫更加容易,3.1 又新增了一個工具類。app
若是你不知道 View 的新增屬性,須要先回顧上一篇文章中標題爲「View properties」的一節內容,而後閱讀本文。函數
使用 ObjectAnimator 爲 View 的屬性作動畫,須要建立一個 Animator,設置動畫的時間參數、值參數、目標對象、目標屬性的名字,就能夠播放動畫了。好比,漸隱某個視圖 myView
,能夠對屬性 alpha
施加動畫:工具
ObjectAnimator.ofFloat(myView, "alpha", 0f).start();
這雖然容易,但仍有很大的改進空間。考慮到視圖屬性會常常用來作動畫,應該引入一些新的 API,使得實現動畫的代碼簡單且可讀,同時還需改善視圖屬性動畫的性能。3.0 動畫機制中關於視圖屬性的性能有三處值得改善:
其一,咱們在一個沒有內建「屬性概念」的語言中作屬性動畫。因爲系統運行時對「屬性」沒概念,所以 ObjectAnimator 須要經過特殊手段把「表明屬性名稱的字符串」變成對「目標對象屬性的 setter 方法」的調用。好比遇到字符串 "alpha"
就知道該去調用 View.setAlpha()
。這種間接手段被稱爲反射 reflection 或者 JNI(java native interface),雖然可靠但會帶來額外開銷。基於對視圖屬性的瞭解,咱們應該提供一些 API 使得動畫能夠直接操做屬性,避開這種間接手段。
譯註:若是不理解上述內容,應該回顧上篇文章「Animation in Honeycomb」中 ObjectAnimator 一節對「隱含的條件」的解釋。
其二,有些情景中可能須要同時對一個 View 的多個屬性作動畫。雖然全部動畫共享計時機制而不會因計時產生額外開銷,但多個屬性動畫須要構造多個 Animator 對象。既然咱們知道要對 View 的哪幾個屬性作動畫,就應該考慮將多個動畫合併成一個,以減小開銷。一種方法是使用 PropertyValuesHolder
,它容許僅構造一個 Animator 對象,就能夠實現多個屬性動畫。但這種方法須要更多的代碼,對簡單的動畫而言過於笨重。應該有一種新的方法既能實現咱們的指望,同時代碼也是簡單易讀的。
譯註:若是不理解上述內容,應該回顧上篇文章「Animation in Honeycomb」中 AnimatorSet 一節內容。
其三,View 的每個屬性都會執行一些操做以確保視圖對象及其父對象在合適的時候重繪。好比, 在 x 軸平移視圖,會使視圖過去和如今的位置失效,以確保父視圖正確地重繪它。而在 y 軸平移視圖,也會作相似的操做。若是這兩個屬性同時改變,還作雙份的重繪工做就顯得多餘。因此應該將這些工做合併在一塊兒。ViewPropertyAnimator
能夠作到。
ViewPropertyAnimator 提供了一種並行屬性動畫的簡單方法。只需構建一個 Animator(譯註:針對上述2);可以直接修改目標視圖的屬性值(譯註:針對上述1);優化重繪工做,使多個屬性的重繪僅發生一次(譯註:針對上述3)。
那麼上述漸隱視圖的代碼能夠這樣寫:
myView.animate().alpha(0);
簡單、易讀。且容易組合多個屬性動畫,好比移動到 (50, 100):
myView.animate().x(50).y(100);
關於上述兩行代碼有幾件事情值得一說:
animate()
:從調用 View 對象的 animate() 方法開始,該方法返回一個 ViewPropertyAnimator 實例,而後就能夠調用它的方法來設置動畫參數。
自動開始:要注意上述兩行代碼並未調用 start() 方法,由於在新 API 中動畫啓動是隱式的,一旦聲明完,這些動畫就「馬上」「一塊兒」啓動了。若是要深究細節的話,其實也並不是「馬上」啓動,而是在下一次 UI 刷新時。ViewPropertyAnimator 正是利用了這個時間差,把全部聲明的動畫收集在一塊兒。只要還在繼續聲明新的動畫,那麼全部動畫就會繼續等待下一次 UI 刷新。一旦完成聲明,全部動畫就在下一次 UI 刷新時一塊兒啓動了。
流式接口:ViewPropertyAnimator 擁有流式接口(Fluent interface),容許函數鏈式調用,使得在一行代碼中能夠構建多個屬性動畫。
代碼確實簡單且易讀了,但性能提高從何而來呢?
性能提高一,可以直接修改目標視圖的屬性,再也不贅述。
性能提高二,只需構建一個 Animator 就能夠實現多個動畫。
若是採用 AnimatorSet 實現的話,須要這樣作,這段代碼建立了兩個 Animator 對象(也就是兩個獨立的動畫),而後經過 AnimatorSet 同時播放:
ObjectAnimator animX = ObjectAnimator.ofFloat(myView, "x", 50f); ObjectAnimator animY = ObjectAnimator.ofFloat(myView, "y", 100f); AnimatorSet animSetXY = new AnimatorSet(); animSetXY.playTogether(animX, animY); animSetXY.start();
或者使用 PropertyValuesHolder
,只構造一個 Animator 對象來同時實現多個屬性動畫:
PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 50f); PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 100f); ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvyY).start();
而使用 ViewPropertyAnimator 實現的代碼已經在上節內容中提到了。
性能提高三,ViewPropertyAnimator 會在每個動畫幀,計算變化的屬性值並設置給屬性,而後只調用一次 invalidate 進行重繪。代替每個屬性單獨計算、單獨重繪。
以上講這麼多,並不意味着 ViewPropertyAnimator 能夠取代 3.0 中 animation 相關的 API。事實上 3.0 相關 API 爲 ViewPropertyAnimator 甚至整個系統的動畫功能提供了重要的支持。ObjectAnimator 能夠靈活方便爲任何對象和屬性作動畫。但當須要同時爲 View 的多個屬性(SDK提供的,非自定義擴展的)作動畫時,ViewPropertyAnimator 會更方便。
還要注意的是:使用 ObjectAnimator 時並不須要太過擔憂性能,使用反射和 JNI 等帶來的開銷相對整個程序來說都是較小的。使用 ViewPropertyAnimator 最大的優點也不在於性能的提高,對我來說,而是它提供的簡明易讀的代碼書寫方式。
版權聲明:《「譯」Android ViewPropertyAnimator 介紹》由 WeiYi.Li 在 2016年02月01日寫做。著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。
文章連接:http://li2.me/2016/02/introducing-androi...