天天看點

Android動畫之PropertyAnimation;Interpolator;Evaluator與Keyframe

概述

Android中的視圖動畫和幀動畫可以實作大部分的Android中的動畫需求,但是有一個缺點,就是其事件響應區域并沒有發生變化,這時候出現了屬性動畫完全彌補了這個缺點

屬性動畫結構

Android動畫之PropertyAnimation;Interpolator;Evaluator與Keyframe

可以看到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: 動畫構造器,用于設定

    AnimatorSet

    PropertyValuesHolder: 用于同時設定多個屬性動畫.

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:源碼及圖解

繼續閱讀