概述
Android中的視圖動畫和幀動畫可以實作大部分的Android中的動畫需求,但是有一個缺點,就是其事件響應區域并沒有發生變化,這時候出現了屬性動畫完全彌補了這個缺點
屬性動畫結構
可以看到Animator中主要包括AnimatorSet(動畫集合),ValueAnimator,ObjectAnimator,
關于屬性動畫相關api,可以檢視這裡android.animation,
屬性動畫執行時間預設為
300ms.
相關類
-
監聽器類
Animator.AnimatorListener:動畫監聽器
Animator.AnimatorPauseListener:動畫暫停監聽器
ValueAnimator.AnimatorUpdateListener:屬性更新監聽器
AnimatorListenerAdapter:AnimatorListener空實作類
-
TypeEvaluator 估值類
IntEvaluator: Int 估值計算
FloatEvaluator: Float 估值計算
ArgbEvaluator: 顔色估計算
-
生成相關類
AnimatorInflater: 動畫生成器,用于從xml生成動畫
AnimatorSet.Builder: 動畫構造器,用于設定
PropertyValuesHolder: 用于同時設定多個屬性動畫.AnimatorSet
ObjectAnimator
ObjectAnimator 不像ValueAnimator 那樣需要使用者自己來更新屬性,會自動跟新,ObjectAnimator 同樣可以在xml和代碼中設定.
- xml 設定,需要放在animator目錄下
<!--res/animator/object_animator-->
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="3000"
android:propertyName="width"
android:valueFrom="100"
android:valueTo="20"
android:valueType="intType" />
ObjectAnimator objectAnimator =
(ObjectAnimator) AnimatorInflater.loadAnimator(this, R.animator.object_animator);
objectAnimator.setTarget(wrapper);
objectAnimator.start();
- 代碼設定
ObjectAnimator animator = ObjectAnimator.ofFloat(_view, "translationX", );
animator.setDuration();
animator.start();
ObjectAnimator 提供了ofInt、ofFloat、ofObject.其中可以設定的屬性必須提供
set/get
方法,如果沒有,可以通過包裝類實作,如下執行個體
public class ViewWrapper {
private View target; //目标對象
private int maxWidth; //最長寬度值
public ViewWrapper(View target, int maxWidth) {
this.target = target;
this.maxWidth = maxWidth;
}
public int getWidth() {
return target.getLayoutParams().width;
}
public void setWidth(int widthValue) {
//widthValue的值從100到20變化
target.getLayoutParams().width = maxWidth * widthValue / ;
target.requestLayout();
}
}
ValueAnimator
ValueAnimator類可以為一些動畫指定一系列的int,float,color值。通過調用工廠方法ofInt(),ofFloat(),ofObject()來擷取一個ValueAnimator.但是ValueAnimator需要在監聽器中擷取屬性值,更新相關屬性
ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", f, f);
fadeAnim.setDuration();
fadeAnim.addListener(new AnimatorUpdateListener() {
//...這裡也可以用AnimatorListenerAdapter,而不用實作每個回調方法
}
其他常用方法
Object getAnimatedValue(); // 擷取目前屬性值,可以使int,float,Object
void cancel();//取消動畫,動畫結束在目前屬性值
/**
* 移除AnimatorUpdateListener
*/
void removeUpdateListener(AnimatorUpdateListener listener);
void removeAllUpdateListeners();
/**
* 移除AnimatorListener
*/
void removeListener(AnimatorListener listener);
void removeAllListeners();
AnimatorSet
可以将多個動畫按照一定的順序來一起執行,可以通過代碼和xml設定
ObjectAnimator anim1 = ObjectAnimator.ofFloat(mBlueBall, "scaleX",
f, f);
ObjectAnimator anim2 = ObjectAnimator.ofFloat(mBlueBall, "scaleY",
f, f);
AnimatorSet animSet = new AnimatorSet();
animSet.setDuration();
animSet.setInterpolator(new LinearInterpolator());
//兩個動畫同時執行
animSet.playTogether(anim1, anim2);
animSet.start();
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="together">
<objectAnimator
... />
<objectAnimator
.../>
</set>
AnimatorSet支援鍊式調用,比如
animSet.play().with();
包含with(),before(),after(),
PropertyValuesHolder
同時在屬性動畫中提供了一個快捷方式來建立動畫,就是PropertyValuesHolder,利用
ObjectAnimator
的
ofPropertyValuesHolder
方法即可生成其執行個體.
PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("alpha", f,
f, f);
PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("scaleX", f,
, f);
PropertyValuesHolder pvhZ = PropertyValuesHolder.ofFloat("scaleY", f,
, f);
ObjectAnimator.ofPropertyValuesHolder(view, pvhX, pvhY,pvhZ).setDuration().start();
PropertyValuesHolder方法定義
public static PropertyValuesHolder ofFloat(String propertyName, float... values);
public static PropertyValuesHolder ofInt(String propertyName, int... values);
TimeAnimator
它沒有duration、interpolation以及設定值的方法,提供了一個簡單的回調機制,通過 TimeAnimator.TimeListener,在動畫的每一幀處通知你
//animation:發出通知的動畫
//totalTime:動畫開始以來的總時間,以毫秒為機關
//deltaTime:從前一幀到現在的運作時間,以毫秒為機關
onTimeUpdate(TimeAnimator animation, long totalTime, long deltaTime)
animate
在Android 3.0 之後,還可以使用animate方法來完成屬性動畫操作,無需調用start()方法,隻需要設定相應屬性和執行時間即可
mView.animate().x().y().setDuration();
Interpolators
Interpolator class | Resource ID | Description |
---|---|---|
AccelerateDecelerateInterpolator | @android:anim/accelerate_decelerate_interpolator | 在動畫開始與結束時速率改變比較慢,在中間的時候加速 |
AccelerateInterpolator | @android:anim/accelerate_interpolator | 在動畫開始時速率改變比較慢,然後開始加速 |
AnticipateInterpolator | @android:anim/anticipate_interpolator | 動畫開始的時候向後然後往前抛 |
AnticipateOvershootInterpolator | @android:anim/anticipate_overshoot_interpolator | 動畫開始的時候向後然後向前抛,會抛超過目标值後再傳回到最後的值 |
BounceInterpolator | @android:anim/bounce_interpolator | 動畫結束的時候會彈跳 |
CycleInterpolator | @android:anim/bounce_interpolator | 動畫循環做周期運動,速率改變沿着正弦曲線 |
DecelerateInterpolator | @android:anim/decelerate_interpolator | 在動畫開始時速率改變比較快,然後開始減速 |
LinearInterpolator | @android:anim/decelerate_interpolator | 動畫勻速播放 |
OvershootInterpolator | @android:anim/overshoot_interpolator | 動畫向前抛,會抛超過最後值,然後再傳回 |
自定義Interpolator
一: 繼承Interpolator或其子類
private class DeceAcceInterpolator implements Interpolator{
@Override public float getInterpolation(float input) {
return ((*input-)*(*input-)*(*input-))/f + f;
}
}
二: 自定義xml,更改屬性
其中可設定屬性包括
Interpolator class | Attribute Name |
---|---|
accelerateInterpolator | android:factor(浮點值,加速的速率,預設為1) |
anticipateInterpolator | android:tension(浮點值,向後的拉力,預設為2,當設為0時,則不會有向後的動畫了) |
anticipateOvershootInterpolator | android:tension(同上),android:extraTension(浮點值,拉力的倍數,預設為1.5,當設為0時,則不會有向後的動畫了) |
cycleInterpolator | android:cycles (整數值,循環的次數,預設為1) |
decelerateInterpolator | android:factor(浮點值,減速的速率,預設為1) |
overshootInterpolator | android:tension(浮點值,超出終點後的拉力,預設為2) |
示例:
<!--res/anim/over_interpolator.xml-->
<?xml version="1.0" encoding="utf-8"?>
<overshootInterpolator xmlns:android="http://schemas.android.com/apk/res/android"
android:tension="7.0"/>
<!--res/anim/rotate_one_rotate.xml-->
<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:duration="2000"
android:fromDegrees="0"
android:pivotX="50%"
android:pivotY="50%"
android:interpolator="@anim/my_interpolator"
android:toDegrees="360"/>
Evaluator
Evaluator其實就是一個轉換器,将Interpolator的fraction轉變為對應屬性的值,如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));
}
}
系統預設實作有
IntEvaluator
,
FloatEvaluator
,
ArgbEvaluator
當沒有設定的時候,如果使用的是
ofFloat
,則預設使用的是
FloatEvaluator
具體參考;自定義控件三部曲之動畫篇(五)——ValueAnimator進階進階(一)
Keyframe
Keyframe的意思是關鍵幀的意思,首先看一下
Keyframe
的定義
//fraction:表示目前的顯示進度.value:表示目前應該在的位置
public static Keyframe ofFloat(float fraction, float value);
同時,可以利用
PropertyValuesHolder
的
ofKeyframe
方法生成
PropertyValuesHolder
執行動畫 .
public static PropertyValuesHolder ofKeyframe(String propertyName, Keyframe... values);
注意的是至少要有兩個幀才行,否則會抛出數組越界異常.
執行個體
Keyframe frame1 = Keyframe.ofFloat(f, f);
Keyframe frame2 = Keyframe.ofFloat(f,f);
PropertyValuesHolder frameHolder = PropertyValuesHolder.ofKeyframe("rotation",frame1,frame2);
Animator animator = ObjectAnimator.ofPropertyValuesHolder(mImage, frameHolder);
animator.setDuration();
animator.start();
具體參考;自定義控件三部曲之動畫篇(八)——PropertyValuesHolder與Keyframe
示例源碼位址;AndroidAnimations
參考:Android樣式的開發:Property Animation篇
第七章 Android動畫機制與使用技巧
自定義控件三部曲之動畫篇(八)——PropertyValuesHolder與Keyframe
擴充閱讀動畫系列 - PropertyAnim 詳解
自定義控件三部曲之動畫篇(五)——ValueAnimator進階進階(一)
動畫系列 - PropertyAnim 實際應用
淺析Android動畫(三),自定義Interpolator與TypeEvaluator
Android中的動畫插值器Interpolator:源碼及圖解