动画七、动画的PropertyValuesHolder与Keyframe
本學(xué)習(xí)筆記主要來自啟艦:
http://blog.csdn.net/harvic880925/article/details/50752838
在學(xué)習(xí)過程中融入了自己的理解和思路。
前面掌握了ValueAnimator、ObjectAnimator動畫通過通過ofInt(), ofFloat(), ofObject()等方式創(chuàng)建實例,實際上動畫實例的創(chuàng)建還有另外的方法:
//valueAnimator的 public ValueAnimator ofPropertyValuesHolder(PropertyValuesHolder... values){} // ObjectAnimator的 public ObjectAnimator ofPropertyValuesHolder(Object target,PropValueHolder... values){}也就是說ValueAnimator和ObjectAnimator除了通過ofInt(), ofFloat(), ofObject()創(chuàng)建實例外,還都有一個ofPropertyValuesHolder()方法來創(chuàng)建實例,這篇文章我就帶大家來看看如何通過ofPropertyValuesHolder()來創(chuàng)建實例的。
由于ValueAnimator和ObjectAnimator都具有ofPropertyValuesHolder()函數(shù),使用方法也差不多,相比而言,ValueAnimator的使用機(jī)會不多,這里我們就只講ObjectAnimator中ofPropertyValuesHolder()的用法。相信大家懂了這篇以后,再去看ValueAnimator的ofPropertyValuesHolder(),也應(yīng)該是會用的。
一、PropertyValuesHolder
1、概述
PropertyValuesHolder的意義是:它其中保存了動畫過程中所需要操作的屬性和對應(yīng)的值。我們通過ofFloat(Object target, String propertyName, float… values)構(gòu)造的動畫,ofFloat()的內(nèi)部實現(xiàn)其實就是將傳進(jìn)來的參數(shù)封裝成PropertyValuesHolder實例來保存動畫狀態(tài)。在封裝成PropertyValuesHolder實例以后,后期的各種操作也是以PropertyValuesHolder為主。
PropertyValuesHolder中有很多函數(shù),有些函數(shù)的api等級是11,有些函數(shù)的api等級是14和21; 高api的函數(shù)我們就不講了,只講講api 11的函數(shù)的用法。
首先,我們來看看創(chuàng)建實例的函數(shù):
public PropertyValuesHolder ofFloat(String propertyName, float... values){} public PropertyValuesHolder ofInt(String propertyName, int... values){} public PropertyValuesHolder ofObject(String propertyName, TypeEvaluator evaluator,Object... values){} public PropertyValuesHolder ofKeyframe(String propertyName, Keyframe... values){}這一段我們著重講ofFloat、ofInt和ofObject的用法,ofKeyframe我們單獨講。
2、PropertyValuesHolder之ofFloat()、ofInt()
(1)ofFloat()、ofInt():
我們先來看看它們的構(gòu)造函數(shù):
propertyName:表示ObjectAnimator需要操作的屬性名。即ObjectAnimator需要通過反射查找對應(yīng)屬性的setProperty()函數(shù)的那個property.
values:屬性所對應(yīng)的參數(shù),同樣是可變長參數(shù),可以指定多個,還記得我們在ObjectAnimator中講過,如果只指定了一個,那么ObjectAnimator會通過查找getProperty()方法來獲得初始值。
(2)、ObjectAnimator.ofPropertyValuesHolder()
public static ObjectAnimator ofPropertyValuesHolder(Object target,PropertyValuesHolder... values){}target:指需要執(zhí)行動畫的控件;
values:是一個可變長參數(shù),可以傳進(jìn)去多個PropertyValuesHolder實例,由于每個PropertyValuesHolder實例都會針對一個屬性做動畫,所以如果傳進(jìn)去多個PropertyValuesHolder實例,將會對控件的多個屬性同時做動畫操作。
下面我們就舉個例子來說明如何通過PropertyValuesHolder的ofFloat、ofInt來做動畫。
private void doPropertyAnimator() {PropertyValuesHolder holder = PropertyValuesHolder.ofFloat("Rotation",60f, -60f, 50f, -50f, -40f, 40f, 30f, -30f, 20f, -20f, 10f, -10f, 0f);PropertyValuesHolder holderColor = PropertyValuesHolder.ofInt("BackgroundColor", 0xfffffff0, 0xffff00ff, 0xffffff00, 0xffffff0f);objectAnimator = ObjectAnimator.ofPropertyValuesHolder(mFlAnimator, holder, holderColor);objectAnimator.setDuration(500);objectAnimator.setRepeatMode(ValueAnimator.REVERSE);objectAnimator.setRepeatCount(ValueAnimator.INFINITE);objectAnimator.setInterpolator(new LinearInterpolator());objectAnimator.start(); }其中,mFlAnimator是自定義TextView(ObjTextView)在xml中的布局,ObjTextView如下:
public class ObjTextView extends TextView {public ObjTextView(Context context, AttributeSet attrs) {super(context, attrs);}public void setCharText(Character character){setText(String.valueOf(character));} }Holder對象設(shè)定了動畫旋轉(zhuǎn)的角度,holderColor對象設(shè)定了動畫的背景色變化,objectAnimator動畫對象里面添加了target控件對象及可變參數(shù)Holder和holderColor,當(dāng)然我們還可以在這里添加別的參數(shù),比如透明度(alpha)的變化,縮放(scale)等動畫效果。
3、PropertyValuesHolder之ofObject()
(1)、概述
我們先來看一下ofObject的構(gòu)造函數(shù):
參數(shù)的含義,再次不多說,不懂的話就找根面條上吊得了。
(2)、示例
這段代碼簡單,前面也已經(jīng)講解過很多次了,不多說,不懂的話就找根面條上吊得了。
public class ObjTextView extends TextView {public ObjTextView(Context context, AttributeSet attrs) {super(context, attrs);}public void setCharText(Character character){setText(String.valueOf(character));} }從CharEvaluator中可以看出,從CharEvaluator中產(chǎn)出的動畫中間值類型為Character類型。TextView中雖然有setText(CharSequence text) 函數(shù),但這個函數(shù)的參數(shù)類型是CharSequence,而不是Character類型。所以我們要自定義一個類派生自TextView來改變TextView的字符:
public class ObjTextView extends TextView {public ObjTextView(Context context, AttributeSet attrs) {super(context, attrs);}public void setCharText(Character character){setText(String.valueOf(character));} }這個與之前上面的相同。
動畫的代碼如下:
private void doPropertyObjAnimator() {PropertyValuesHolder holderText = PropertyValuesHolder.ofObject("CharText", new CharEvaluator(), new Character('A'), new Character('Z'));PropertyValuesHolder holder = PropertyValuesHolder.ofFloat("Rotation", 60f, -60f, 50f, -50f, -40f, 40f, 30f, -30f, 20f, -20f, 10f, -10f, 0f);PropertyValuesHolder holderColor = PropertyValuesHolder.ofInt("BackgroundColor", 0xfffffff0, 0xffff00ff, 0xffffff00, 0xffffff0f);objectAnimator01 = ObjectAnimator.ofPropertyValuesHolder(mFlAnimator, holderText, holder, holderColor);objectAnimator01.setDuration(2000);objectAnimator01.setInterpolator(new LinearInterpolator());objectAnimator01.setRepeatCount(ValueAnimator.INFINITE);objectAnimator01.setRepeatMode(ValueAnimator.REVERSE);objectAnimator01.start(); }首先是根據(jù)PropertyValuesHolder.ofObject生成一個PropertyValuesHolder實例,注意它的屬性就是CharText,所對應(yīng)的set函數(shù)就是setCharText,由于CharEvaluator的中間值是Character類型,所以CharText屬性所對應(yīng)的完整的函數(shù)聲明為setCharText(Character character);這也就是我們?yōu)槭裁匆远x一個MyTextView原因,就是因為TextView中沒有setText(Character character)這樣的函數(shù)。
二、Keyframe
1、概述:KeyFrame直譯過來就是關(guān)鍵幀。 一個關(guān)鍵幀必須包含兩個原素,第一時間點,第二位置。即這個關(guān)鍵幀是表示的是某個物體在哪個時間點應(yīng)該在哪個位置上。
KeyFrame的生成方式為:
Keyframe kf0 = Keyframe.ofFloat(0, 0); Keyframe kf1 = Keyframe.ofFloat(0.1f, -20f); Keyframe kf2 = Keyframe.ofFloat(1f, 0);上面生成了三個KeyFrame對象,其中KeyFrame的ofInt函數(shù)的聲明為:
public static Keyframe ofFloat(float fraction, float value);fraction:表示當(dāng)前的顯示進(jìn)度,即從加速器中g(shù)etInterpolation()函數(shù)的返回值;
value:表示當(dāng)前應(yīng)該在的位置
比如Keyframe.ofFloat(0, 0)表示動畫進(jìn)度為0時,動畫所在的數(shù)值位置為0;Keyframe.ofFloat(0.25f, -20f)表示動畫進(jìn)度為25%時,動畫所在的數(shù)值位置為-20;Keyframe.ofFloat(1f,0)表示動畫結(jié)束時,動畫所在的數(shù)值位置為0;
在理解了KeyFrame.ofFloat()的參數(shù)以后,我們來看看PropertyValuesHolder是如何使用KeyFrame對象的:
public static PropertyValuesHolder ofKeyframe(String propertyName, Keyframe... values);fraction:表示當(dāng)前的顯示進(jìn)度,即從加速器中g(shù)etInterpolation()函數(shù)的返回值;
value:表示當(dāng)前應(yīng)該在的位置
2、示例:
private void doOfFloatAnim(){Keyframe frame0 = Keyframe.ofFloat(0f, 0);Keyframe frame1= Keyframe.ofFloat(0.1f, -20f);Keyframe frame2 = Keyframe.ofFloat(0.2f, 20f);Keyframe frame3 = Keyframe.ofFloat(0.3f, -20f);Keyframe frame4 = Keyframe.ofFloat(0.4f, 20f);Keyframe frame5 = Keyframe.ofFloat(0.5f, -20f);Keyframe frame6 = Keyframe.ofFloat(0.6f, 20f);Keyframe frame7 = Keyframe.ofFloat(0.7f, -20f);Keyframe frame8 = Keyframe.ofFloat(0.8f, 20f);Keyframe frame9 = Keyframe.ofFloat(0.9f, -20f);Keyframe frame10 = Keyframe.ofFloat(1, 0);frameHolder = PropertyValuesHolder.ofKeyframe("rotation", frame0, frame1, frame2, frame3, frame4, frame5, frame6, frame7, frame8, frame9, frame10);frameHolder.setEvaluator(new CharEvaluator());animator = ObjectAnimator.ofPropertyValuesHolder(mIvKeyframe, frameHolder);animator.setDuration(500);animator.setInterpolator(new LinearInterpolator());animator.start(); }3、Keyframe之ofFloat、ofInt與常用函數(shù)
(1)、ofFloat、ofInt
其實Keyframe除了ofFloat()以外,還有ofInt()、ofObject()這些創(chuàng)建Keyframe實例的方法,Keyframe.ofObject()我們下部分再講,這部分,我們著重看看ofFloat與ofInt的構(gòu)造函數(shù)與使用方法:
2)、常用函數(shù):
//設(shè)置fraction參數(shù),即Keyframe所對應(yīng)的進(jìn)度; public void setFraction(float fraction) // 設(shè)置當(dāng)前Keyframe所對應(yīng)的值; public void setValue(Object value) // 設(shè)置Keyframe動作期間插值器; public void setInterpolator(TimeInterpolator interpolator)這三個函數(shù)中,插值器的作用應(yīng)該是比較難理解,如果給這個Keyframe設(shè)置上插值器,那么這個插值器就是從上一個Keyframe開始到當(dāng)前設(shè)置插值器的Keyframe時,這個過程值的計算是利用這個插值器的,比如:
Keyframe frame0 = Keyframe.ofFloat(0f, 0); Keyframe frame1 = Keyframe.ofFloat(0.1f, -20f); frame1.setInterpolator(new BounceInterpolator()); Keyframe frame2 = Keyframe.ofFloat(1f, 20f); frame2.setInterpolator(new LinearInterpolator());在上面的代碼中,我們給frame1設(shè)置了插值器BounceInterpolator,那么在frame0到frame1的中間值計算過程中,就是用的就是回彈插值器;
同樣,我們給frame2設(shè)置了線性插值器(LinearInterpolator),所以在frame1到frame2的中間值計算過程中,使用的就是線性插值器。很顯然,給Keyframe.ofFloat(0f, 0)設(shè)置插值器是無效的,因為它是第一幀。
4、Keyframe之ofObject
與ofInt,ofFloat一樣,ofObject也有兩個構(gòu)造函數(shù):
同樣,如果使用ofObject(float fraction)來構(gòu)造,也必須使用setValue(Object value)來設(shè)置這個關(guān)鍵幀所對應(yīng)的值。我們還以TextView更改字母的例子來使用下Keyframe.ofObject.
private void doKeyframeofObject(){Keyframe frame0 = Keyframe.ofObject(0f, new Character('A'));Keyframe frame1 = Keyframe.ofObject(0.1f, new Character('L'));Keyframe frame2 = Keyframe.ofObject(1,new Character('Z'));frameHolder02 = PropertyValuesHolder.ofKeyframe("CharText",frame0,frame1,frame2);frameHolder02.setEvaluator(new CharEvaluator());animator02 = ObjectAnimator.ofPropertyValuesHolder(mFlAnimator, frameHolder);animator02.setDuration(3000);animator02.start(); }利用關(guān)鍵幀創(chuàng)建PropertyValuesHolder后,一定要記得設(shè)置自定義的Evaluator:
frameHolder02.setEvaluator(new CharEvaluator());凡是使用ofObject來做動畫的時候,都必須調(diào)用frameHolder.setEvaluator顯示設(shè)置Evaluator,因為系統(tǒng)根本是無法知道,你動畫的中間值Object真正是什么類型的。
如果去掉第0幀,將以第一個關(guān)鍵幀為起始位置
如果去掉結(jié)束幀,將以最后一個關(guān)鍵幀為結(jié)束位置
使用Keyframe來構(gòu)建動畫,至少要有兩個或兩個以上幀
三、PropertyValuesHolder的其它函數(shù)
// 設(shè)置動畫的Evaluator public void setEvaluator(TypeEvaluator evaluator);// 用于設(shè)置ofFloat所對應(yīng)的動畫值列表 public void setFloatValues(float... values);// 用于設(shè)置ofInt所對應(yīng)的動畫值列表 public void setIntValues(int... values);// 用于設(shè)置ofKeyframe所對應(yīng)的動畫值列表 public void setKeyframes(Keyframe... values);// 用于設(shè)置ofObject所對應(yīng)的動畫值列表 public void setObjectValues(Object... values);// 設(shè)置動畫屬性名 public void setPropertyName(String propertyName);這些函數(shù)都比較好理解。
如果是利用PropertyValuesHolder.ofObject()來創(chuàng)建動畫實例的話,我們是一定要顯示調(diào)用 PropertyValuesHolder.setEvaluator()來設(shè)置Evaluator的。謹(jǐn)記!謹(jǐn)記!!謹(jǐn)記!!!
總結(jié)
以上是生活随笔為你收集整理的动画七、动画的PropertyValuesHolder与Keyframe的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: win10更新(windows upda
- 下一篇: Windows 2D 绘图 (GDI,