又和大家見面了,筆者想問一下,大家有沒有用上次的那個表白神器啊,那麼醜的界面可能有不少人被吐槽了吧哈哈。。。。這個不是今天的重點。還記得我們的動畫效果是怎麼實現的嗎:
我們用ValueAnimator設置監聽器,然後改變當前桃心的大小,最後重繪動畫。
其實我們發現,我們之前做的案例,幾乎都是用ValueAnimator實現的(可能因爲覺得監聽器接口回調比較炫酷吧-。+),但是ObjectAnimator卻沒怎麼用過,除了最開始介紹屬性動畫是從ObjectAnimator介紹的,但是只是在屬性動畫內置的幾種屬性中,使用了ObjectAnimator。今天在這基礎上,我們來深入瞭解一下ObjectAnimator,然後用ObjectAnimator來實現之前東西。
ObjectAnimator和ValueAnimator原理
關於ObjectAnimator,我們目前只知道,他是繼承了ValueAnimator類,所以ValueAnimator能用的方法,ObjectAnimator幾乎都能用,但是他們的工作原理是有一點不同的,如下圖所示:
我簡單的畫了一張兩種屬性動畫類的工作原理圖,大體上是差不多的,但是ValueAnimator是通過UpdateListener回調,而ObjectAnimator是根據我們給的屬性拼接成set方法,然後通過反射調用。(我們現在就先這裏理解,更深層次的實現流程我會專門寫一篇源碼分析篇。)
我們之前的理解很可能是ObjectAnimator中propertyName屬性是我們填入的target對象的一個屬性,我們更改他的值。而現在我們知道了,我們是調用的對應set方法。我們舉個簡單的例子:
我們propertyName中填入的是translationX,那我們去TextView中看看到底有沒有這個屬性,其實是沒有的,大家下去自己查,再去View中看看有沒有,也沒有,但是父類View中有一個方法叫做setTranslationX
結論:他是通過拼接對應set方法,再通過反射調用的。而不是裏面這個屬性。
也就是說,我們propertyName中填寫的是控件對應set方法的方法名:加入有一個setAsd方法,那麼我們在propertyName中寫asd或者Asd就可以了。
以下是我對ObjectAnimator使用的總結:
我們結合實例來驗證一下這些,就用我們上次做的小球來驗證吧。
效果如下:
這是我們之前用ValueAnimator實現的,現在我們用ObjectAnimator實現
我們在PropertyValueHolder中添加了propertyName屬性,爲position,所以我們還需要一個setPosition方法:
效果如下:
跟ValueAnimator是一樣的效果。接下來我們驗證上面幾點:
1.把setPosition方法名改錯。
我們發現小球不動作,然後看一下日誌:
他打印一條verbose級別的log。上面寫的很清楚,不用多說了。
2.添加get方法,當只有一個values時,調用get方法。
這是我們的getPosition方法,我們返回一個新的球,座標爲900,900。
由於KeyFrame不能只有一個,所以我們這次通過ofObject創建動畫,但是隻寫了一個參數,座標爲300,300的球。然後效果:
看來的確從get方法中獲取到的值作爲了起始點,結論正確。
3.set方法修改爲private和protected類型。
我們修改爲protected類型,效果如下:
還是可以動作的,然後改爲private類型:
結論正確。
其餘的應該沒什麼問題了,大家可以下去自己測試一下。
以上便是我們關於ObjectAnimator屬性動畫的詳細解釋。希望大家多多關注一波。