1.前言
上一講的內容大概地了解一下怎樣通過屬性動畫完成常見的需求。但隨著使用,必然會發(fā)現(xiàn)一些不方便的地方,這時候說明我們對屬性動畫的了解還不夠。比如,補間動畫中的位移可以同時改變控件在XY兩個方向上的位置,而屬性動畫卻不可以。雖說是因為補間動畫操作控件的行為(由控件容器處理,與控件本身無關)而屬性動畫改變控件的屬性,原理不一樣,但總顯得不夠強大。那么,我們深入地去學習一下。
2.操作多個屬性

PropertyValuesHolder是用來保存動畫過程中所需要操作的屬性及其對應的值,是ObjectAnimator中的一部分,可以設置多個,由XML屬性與代碼可知。
// API 23在XML中引入,為了同時操作多個屬性
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android">
<propertyValuesHolder android:propertyName="x" android:valueTo="50"/>
<propertyValuesHolder android:propertyName="y" android:valueTo="100"/>
</objectAnimator>
android:propertyName
必需,進行動畫的屬性的名稱,對應控件中setXXX方法(駝峰命名)。映射時,默認只將屬性名第一個字母大寫,所以其它必須符合駝峰命名。
由于執(zhí)行動畫的控件不能在XML中設置,必須在代碼中設置。
代碼表示:setPropertyName(String propertyName)
android:valueTo
必需,動畫結束時屬性的值。
代碼表示:setFloatValues(float... values) / setIntValues(int... values)
android:valueFrom
動畫開始時屬性的值。若沒有指定,將從控件屬性對應的get方法中獲得。若還沒有,則使用數(shù)據類型的默認值。
代碼表示:setFloatValues(float... values) / setIntValues(int... values)
android:valueType
關鍵字,若類型是顏色,不設置此屬性。
floatType是默認值,表示為浮點型。intType,表示為整型。
代碼表示:無相應的方法。
// 快捷的表示方法
// 第一個參數(shù)指定被動畫操作的控件的屬性名,與android:propertyName用法一致。
// 第二個是可變參數(shù),指定動畫值的改變軌跡。由于參數(shù)數(shù)量不定,變化更加靈活。
PropertyValuesHolder.ofFloat(String propertyName, float... values)
PropertyValuesHolder.ofInt(String propertyName, int... values)
// 第一個參數(shù)指定執(zhí)行動畫的控件。
// 第二個是可變參數(shù),指定同時執(zhí)行的屬性。由于參數(shù)數(shù)量不定,變化更加靈活。
ObjectAnimator.ofPropertyValuesHolder(Object target, PropertyValuesHolder... values)
// 也可以通過實例獲取
ObjectAnimator.setValues(PropertyValuesHolder... values)
通過上面的說明已經可以很方便地寫出多屬性的動畫,但是屬性動畫是調用setXXX()方法修改控件的屬性,為了將變化反映到界面上,需調用invalidate()方法重繪視圖。但是各個動畫獨立重繪相當消耗資源,影響體驗,所以API 12推出了ViewPropertyAnimator這一優(yōu)化類。它將統(tǒng)一重繪操作,集中處理各個屬性。并且,封裝了常用的動畫,以鏈式結構提高書寫的便捷。
// 1.首先調用View的方法獲取實例
ViewPropertyAnimator animate ()
// 2.常用屬性 alpha / rotation / rotationX / rotationY / scaleX / scaleY / translationX / translationY / translationZ / x / y / z
ViewPropertyAnimator XXX(float value)
設置屬性的結束值
ViewPropertyAnimator XXXBy(float value)
設置屬性的開始值
// 3.其它的方法和ObjectAnimator沒太大區(qū)別
// 比如 開始動畫 取消動畫 設置插值器 設置時長 設置延時等
3.復雜動畫
同時改變多個屬性不算是復雜動畫。我們都知道通過代碼可以設置屬性多個控制值,那么這些值在動畫進行中分別位于什么時間點,怎么分布,控制值之間能不能用不同的Interpolator。目前是實現(xiàn)不了的,所以又得引入新的類Keyframe。
// API 23在XML中引入,為了精細操作屬性的變化
<propertyValuesHolder android:propertyName="x" >
<keyframe android:fraction="0" android:value="800" />
<keyframe android:fraction=".2"
android:interpolator="@android:anim/accelerate_interpolator"
android:value="1000" />
<keyframe android:fraction="1"
android:interpolator="@android:anim/accelerate_interpolator"
android:value="400" />
</propertyValuesHolder>
android:fraction
設置此關鍵幀在整個動畫周期中的百分比,從0到1,至少保留兩幀。
代碼表示:setFraction(float fraction)
android:interpolator
設置從前一幀到當前幀所用的插值器,默認是 AccelerateDecelerateInterpolator。
代碼表示:setInterpolator(TimeInterpolator interpolator)
android:value
設置此關鍵幀的屬性值。
代碼表示:abstract void setValue(Object value)
android:valueType
關鍵字,若類型是顏色,不設置此屬性。
floatType是默認值,表示為浮點型。intType,表示為整型。
代碼表示:無相應的方法。
// 快捷的表示方法
// 第一個參數(shù)指定此關鍵幀在整個動畫周期中的百分比,與android:fraction用法一致。
// 第二個參數(shù)指定此關鍵幀的屬性值。
Keyframe.ofFloat(float fraction, float value)
Keyframe.ofInt(float fraction, int value)
// 與setValue()方法配合實現(xiàn)
Keyframe.ofFloat(float fraction)
Keyframe.ofInt(float fraction)
// 第一個參數(shù)指定被動畫操作的控件的屬性名,與android:propertyName用法一致。
// 第二個是可變參數(shù),指定關鍵幀的系列變化。由于參數(shù)數(shù)量不定,變化更加靈活。
PropertyValuesHolder.ofKeyframe(String propertyName, Keyframe... values)
// 也可以通過實例獲取
PropertyValuesHolder.setKeyframes(Keyframe... values)
4.總結
通過兩篇的講解,對于屬性動畫已經有了整體的認識,我們來串聯(lián)一下。ObjectAnimator作為動畫的單元,可以設置作用對象、改變的屬性、變化的值及插值器等。若動畫想改變多個屬性,要么放到集合中,要么通過PropertyValuesHolder擴展ObjectAnimator改變的屬性數(shù)量。PropertyValuesHolder作為屬性的單元,可以設置改變的屬性、變化的值。要想精細地控制動畫,只能通過Keyframe擴展PropertyValuesHolder的屬性值在時間上的分布及動畫變化效果。這些都可以通過XML配置,用AnimatorInflater加載。