多屬性變化
給同一個View實現同一個動畫效果(同時變化x和y),有下面三種方法。
方法一:用多個ObjectAnimator對象
ObjectAnimator animX = ObjectAnimator.ofFloat(myView, "x", 50f);
ObjectAnimator animY = ObjectAnimator.ofFloat(myView, "y", 100f);
AnimatorSet animSetXY = new AnimatorSet();
animSetXY.playTogether(animX, animY);
animSetXY.start();
方法二:用一個ObjectAnimator對象加多個PropertyValuesHolder
PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("x", 50f);
PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("y", 100f);
ObjectAnimator.ofPropertyValuesHolder(myView, pvhX, pvyY).start();
方法三:用ViewPropertyAnimator
myView.animate().x(50f).y(100f);
這三種方法中值得一提的是后兩種方法,其中ViewPropertyAnimator的使用請參見Android屬性動畫完全解析(下),Interpolator和ViewPropertyAnimator的用法中最后一部分的講解。現在來講講PropertyValuesHolder。
PropertyValuesHolder
PropertyValuesHolder這個類可以先將動畫屬性和值暫時的存儲起來,后一起執行,在有些時候可以使用替換掉AnimatorSet,減少代碼量。
主要方法如下:
public static PropertyValuesHolder ofFloat(String propertyName, float... values)
public static PropertyValuesHolder ofInt(String propertyName, int... values)
public static PropertyValuesHolder ofObject(String propertyName, TypeEvaluator evaluator,Object... values)
public static PropertyValuesHolder ofKeyframe(String propertyName, Keyframe... values)
關鍵幀
關鍵幀這個概念是從動畫里學來的,我們知道視頻里,一秒要播放24幀圖片,對于制作flash動畫的同學來講,是不是每一幀都要畫出來呢?當然不是了,如果每一幀都畫出來,那估計做出來一個動畫片都得要一年時間;比如我們要讓一個球在30秒時間內,從(0,0)點運動到(300,200)點,那flash是怎么來做的呢,在flash中,我們只需要定義兩個關鍵幀,在動畫開始時定義一個,把球的位置放在(0,0)點;在30秒后,再定義一個關鍵幀,把球的位置放在(300,200)點。在動畫 開始時,球初始在是(0,0)點,30秒時間內就adobe flash就會自動填充,把球平滑移動到第二個關鍵幀的位置(300,200)點; 通過上面分析flash動畫的制作原理,我們知道,一個關鍵幀必須包含兩個原素,第一時間點,第二位置。即這個關鍵幀是表示的是某個物體在哪個時間點應該在哪個位置上。 所以谷歌的KeyFrame也不例外,KeyFrame的生成方式為:
Keyframe kf0 = Keyframe.ofFloat(0, 0);
Keyframe kf1 = Keyframe.ofFloat(0.1f, -20f);
Keyframe kf2 = Keyframe.ofFloat(1f, 0);
上面生成了三個KeyFrame對象,其中KeyFrame的ofInt函數的聲明為:
public static Keyframe ofFloat(float fraction, float value)
fraction:表示當前的顯示進度,即從加速器中getInterpolation()函數的返回值;
value:表示當前應該在的位置
比如Keyframe.ofFloat(0, 0)表示動畫進度為0時,動畫所在的數值位置為0;Keyframe.ofFloat(0.25f, -20f)表示動畫進度為25%時,動畫所在的數值位置為-20;Keyframe.ofFloat(1f,0)表示動畫結束時,動畫所在的數值位置為0; 在理解了KeyFrame.ofFloat()的參數以后,我們來看看PropertyValuesHolder是如何使用KeyFrame對象的:
public static PropertyValuesHolder ofKeyframe(String propertyName, Keyframe... values)
propertyName:動畫所要操作的屬性名
values:Keyframe的列表,PropertyValuesHolder會根據每個Keyframe的設定,定時將指定的值輸出給動畫。
所以完整的KeyFrame的使用代碼應該是這樣的:
Keyframe frame0 = Keyframe.ofFloat(0f, 0);
Keyframe frame1 = Keyframe.ofFloat(0.1f, -20f);
Keyframe frame2 = Keyframe.ofFloat(1, 0);
PropertyValuesHolder frameHolder = PropertyValuesHolder.ofKeyframe("rotation",frame0,frame1,frame2);
Animator animator = ObjectAnimator.ofPropertyValuesHolder(mImage,frameHolder);
animator.setDuration(1000);
animator.start();
第一步:生成Keyframe對象;
第二步:利用PropertyValuesHolder.ofKeyframe()生成PropertyValuesHolder對象
第三步:ObjectAnimator.ofPropertyValuesHolder()生成對應的Animator