本篇來介紹一下屬性動畫中另一個重要的類ObjectAnimator~
- ObjectAnimator ObjectAnimator是 ValueAnimator的子類,它是可以直接對任意物件的任意屬性進行動畫操作的,因為ValueAnimator是父類,所以ValueAnimator中可以使用的方法在ObjectAnimator中也是可以使用的,ObjectAnimator可以用XML表示,建立object_anim.xml如下:
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:valueTo="200"
android:valueType="floatType"
android:propertyName="y"
android:repeatCount="1"
android:repeatMode="reverse"/>
複製程式碼
程式碼中呼叫XML檔案:
ObjectAnimator objectAnimator = (ObjectAnimator) AnimatorInflater.loadAnimator(this, R.animator.object_anim);
objectAnimator.setTarget(myObject);
objectAnimator.start();
複製程式碼
如果想建立更復雜一些的動畫,需要用到PropertyValuesHolder來對各個屬性分別做動畫,如:
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="1000"
android:repeatCount="1"
android:repeatMode="reverse">
<propertyValuesHolder android:propertyName="x" android:valueTo="400"/>
<propertyValuesHolder android:propertyName="y" android:valueTo="200"/>
</objectAnimator>
複製程式碼
如果想更復雜一些,還要用到keyframe (關鍵幀),fraction是當前進度,取值範圍(0,1),插值器interpolator 是可選的,預設是 AccelerateDecelerateInterpolator,示例:
<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>
<propertyValuesHolder android:propertyName="y" >
<keyframe/>
<keyframe android:fraction=".2"
android:interpolator="@android:anim/accelerate_interpolator"
android:value="300"/>
<keyframe android:interpolator="@android:anim/accelerate_interpolator"
android:value="1000" />
</propertyValuesHolder>
複製程式碼
程式碼中使用ObjectAnimator:
//ofFloat(Object target, String propertyName, float... values)
//第一個引數為object型別的target,這裡是textview
//第二個引數是要做動畫的屬性值
//最後一個可以傳入任意個數的引數,動畫在他們數值之間過渡
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(tv_text, "rotation", 0f, 20f, -20f, 20f, -20f, 0f);
//動畫時長
objectAnimator.setDuration(3000);
//動畫重複次數
objectAnimator.setRepeatCount(2);
//動畫重複模式
objectAnimator.setRepeatMode(ValueAnimator.RESTART);
//設定動畫插值器
objectAnimator.setInterpolator(new AccelerateInterpolator());
//設定監聽器
objectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float value = (float) animation.getAnimatedValue();
Log.e("TTT", "value is " + value);
}
});
//啟動動畫
objectAnimator.start();
複製程式碼
ofFloat()中第二個引數傳入屬性值的是"rotation",那麼這個引數都可以用哪些值呢?答案是任何值!因為ObjectAnimator針對於任意物件的,它的工作就是不斷地向某個物件中的某個屬性進行賦值,然後物件根據屬性值的改變再來決定如何展現出來。系統不會根據這個屬性值名稱去查詢,而是會查詢對應的get和set方法。
上面程式碼效果圖:
上面使用的是ObjectAnimator.ofFloat()來建立浮點數值的ObjectAnimator例項,那麼如果想建立自定義object的ObjectAnimator例項呢?這時就要用ObjectAnimator.ofObject()來建立了,如:
ObjectAnimator ofObject(Object target, String propertyName,TypeEvaluator evaluator, Object... values)
複製程式碼
這裡要用到自定義Evaluator 了,Android 屬性動畫Property Animation(上) 中已經介紹過,Evaluator通過給定的動畫起始值(startValue)和結束值(endValue)以及動畫當前進度(fraction)來計算當前動畫的進度值。先來看下幾個常用的Evaluator, IntEvaluator:
public class IntEvaluator implements TypeEvaluator<Integer> {
public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
int startInt = startValue;
return (int)(startInt + fraction * (endValue - startInt));
}
}
複製程式碼
FloatEvaluator:
public class FloatEvaluator implements TypeEvaluator<Number> {
public Float evaluate(float fraction, Number startValue, Number endValue) {
float startFloat = startValue.floatValue();
return startFloat + fraction * (endValue.floatValue() - startFloat);
}
}
複製程式碼
**返回的當前進度值=起始值+(結束值-起始值) x 當前進度,**ArgbEvaluator也是一樣道理。如果用ofInt()來定義動畫,動畫中的進度值應該都是整形的,如果用ofFloat()來定義動畫,那麼動畫中的值也都是浮點型的。以ofFloat(0.0f,1.0f)為例:起始值為0.0f,結束值是1.0f,假如當前進度(fraction)為50%,則當前進度值=0.0f+(1.0f-0.0f)x 0.5=0.5,在AnimatorUpdateListener監聽器中通過animation.getAnimatedValue()函式拿到Evaluator中返回的值,如果需要自定義Evaluator,則需要實現TypeEvaluator介面:
public class MyEvalutor implements TypeEvaluator {
@Override
public Object evaluate(float fraction, Object startValue, Object endValue) {
return null;
}
}
複製程式碼
下面建立一個自定義object的ObjectAnimator例子,先定義一個ObInfo類:
public class ObInfo implements Serializable {
public int color;//用來定義顏色
public float x; //用來定義X軸
public float y; //用來定義Y軸
public ObInfo(int color, float x, float y) {
this.color = color;
this.x = x;
this.y = y;
}
}
複製程式碼
接著自定義TypeEvaluator :
public class MyEvalutor implements TypeEvaluator<ObInfo> {
@Override
public ObInfo evaluate(float fraction, ObInfo startValue, ObInfo endValue) {
float x = startValue.x + fraction * (endValue.x - startValue.x);
float y = startValue.y + fraction * (endValue.y - startValue.y);
int color = (int) (startValue.color + fraction * (endValue.color - startValue.color));
return new ObInfo(color, x, y);
}
}
複製程式碼
最後實現動畫:
ObInfo info1 = new ObInfo(0xffffff00, 500, 200);
ObInfo info2 = new ObInfo(0xff0000ff, 500, 1000);
ValueAnimator animator = ValueAnimator.ofObject(new MyEvalutor(), info1, info2, info1);
animator.setDuration(4000);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
ObInfo info = (ObInfo) animation.getAnimatedValue();
tv_text.layout(tv_text.getLeft(), (int) info.y, tv_text.getRight(), (int) (info.y + tv_text.getHeight()));
tv_text.setTextColor(info.color);
}
});
animator.start();
複製程式碼
文字先往下移動,再返回原處,移動過程中顏色也不斷變化,效果圖:
如果想監聽動畫過程只需新增監聽器:
objectAnimator.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
//動畫開始前呼叫
}
@Override
public void onAnimationEnd(Animator animation) {
//動畫結束時呼叫
}
@Override
public void onAnimationCancel(Animator animation) {
//動畫取消時呼叫
}
@Override
public void onAnimationRepeat(Animator animation) {
//動畫重複執行時呼叫
}
});
複製程式碼
如果只想用其中的一個,只需改成介面卡類AnimatorListenerAdapter即可:
objectAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationCancel(Animator animation) {
super.onAnimationCancel(animation);
}
});
複製程式碼
常用方法 | 備註 |
---|---|
ofFloat、ofInt、ofArgb、ofObject、ofPropertyValuesHolder | ofFloat(),ofInt(),ofArgb(),ofObject(),ofPropertyValuesHolder()分別是用來建立浮點型、整形、顏色值、自定義object、包含PropertyValuesHolder的animator例項 |