及逐格動畫
但是由於 View Animation 必須作用在 View 上而且只有四種受限的動畫效果
所以其實並不是太好用
API level 11 新增的 Property Animation 則沒有上述的限制
適用於 View 和 非View 的物件,而且物件本身的屬性會確實被修改
舉凡顏色、位置、尺寸等都可以控制
Property Animation 相關的類別幾乎都在 android.animation 這個 package
這其中包含三種角色:Animators, Evaluators, Interpolators
Animators
Animator, ValueAnimator, ObjectAnimator 這幾個家族成員
它們的繼承關係架構如下:
java.lang.Object ↳ android.animation.Animator ↳ android.animation.ValueAnimator ↳ android.animation.ObjectAnimatorAnimator 負責動畫的基本架構的一個類別,通常我們不直接使用
ValueAnimator 是一個計時引擎也負責計算屬性值
它有一個 addUpdateListener(ValueAnimator.AnimatorUpdateListener listener) 的方法
可以讓我們在動畫進行時接收到屬性的變化
而大多數情況下我們使用 ObjectAnimator 因為它比較易於操作
另外負責將動畫組合的類別 android.animation.AnimatorSet 也是繼承自 Animator
Evaluators
Evaluators 是負責告訴 Animator 要如何計算屬性值
當然所需的屬性資料也是由 Animator 來提供
基本上看名稱就可以知道要用哪一個:
IntEvaluator - 當屬性值是 int 時使用 IntEvaluator
FloatEvaluator - 當屬性值是 float 時使用 FloatEvaluator
ArgbEvaluator - 當屬性值是色碼值 ARGB 時使用 ArgbEvaluator
TypeEvaluator - 如果不是以上三種,可能就要自訂 Evaluator,而方式就是實作 TypeEvaluator 這個 interface,而實作的方法可以參考官方文章 Using a TypeEvaluator
Interpolators
Interpolator 定義動畫的線性類型是定速、加速、減速 或先加速後減速之類
也是看名稱就可以猜出功能
AccelerateDecelerateInterpolator - 先加速後減速
AccelerateInterpolator - 加速
AnticipateInterpolator - 先往後再往前
AnticipateOvershootInterpolator - 先往後再超過再回來
BounceInterpolator - 反彈
CycleInterpolator - 週期性重複
DecelerateInterpolator - 減速
LinearInterpolator - 定速
OvershootInterpolator - 超過再回來
TimeInterpolator - 實作 TimeInterpolator 這個 interface 來自訂 Interpolator
接著來看看簡單範例:(修改自 DevBytes: Property Animations)
//static ObjectAnimator ofFloat(Object target, String propertyName, float... values) //property 參數要放屬性名稱,但該屬性要有相對應的setter & getter (例如屬性名稱是"alpha"那就要有 setAlpha(), getAlpha()) //ObjectAnimator android.animation.ObjectAnimator.ofFloat(View target, Property property, float... values) // API 14 之後改成可以使用常數設定 property 參數,如本例為View.TRANSLATION_X,型別為 Property 這樣更易使用 ObjectAnimator translateAnimation = ObjectAnimator.ofFloat(translateButton, View.TRANSLATION_X, 800); translateAnimation.setRepeatCount(1); translateAnimation.setRepeatMode(ValueAnimator.REVERSE); //repeatMode 的預設值是 RESTART //可以注意到這邊我們並沒有呼叫 setDuration 去設定動畫時間 //因為在 ObjectAnimator 裡有預設 duration 是 300 milliseconds // 因為要同時控制 SCALE_X 跟 SCALE_Y 兩個屬性,所以這邊要用 PropertyValuesHolder 來控制 PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat(View.SCALE_X, 2); PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat(View.SCALE_Y, 2); ObjectAnimator scaleAnimation = ObjectAnimator.ofPropertyValuesHolder(scaleButton, pvhX, pvhY); scaleAnimation.setRepeatCount(1); scaleAnimation.setRepeatMode(ValueAnimator.REVERSE); // AnimatorSet 的用法 AnimatorSet animationSet = new AnimatorSet(); animationSet.play(animation2_1).after(animation1).before(animation3); animationSet.play(animation2_2).before(animation3); //注意:這樣寫只能保證animation2_2先於animation3 //不能保證animation2_2與animation1或animation2_1的先後 //老實說這設定方式有點怪,不如使用 xml 來設定順序 //最後呼叫 start() 開始播放 animationSet.start();
另外一樣也可以用 xml 的方式來設定動畫
但是 Property Animation 的檔案應該放在 res/animator/ 資料夾下
跟 View Animation 是不同的,記得別放錯哦
簡單範例如下:
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" android:propertyName="alpha" android:repeatCount="1" android:repeatMode="reverse" android:duration="300" android:valueTo="0"/> <objectAnimator android:propertyName="scaleX" android:repeatCount="1" android:repeatMode="reverse" android:duration="300" android:valueTo="2"/> <objectAnimator android:propertyName="scaleY" android:repeatCount="1" android:repeatMode="reverse" android:duration="300" android:valueTo="2"/>
若來源是 xml 一樣要先取得 Animator 才能 start
Animator anim = AnimatorInflater.loadAnimator(this, animationID); anim.setTarget(view); anim.start();
更新:
在 DevBytes: Bounce Animations 的範例中
示範了一個反彈範例
我們可以從其中 MyView 的 code 裡面比較一下 ValueAnimator 跟 ObjectAnimator 的寫法
//ValueAnimator ValueAnimator anim = ValueAnimator.ofFloat(0, 1); anim.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { setShapeY((int) (animation.getAnimatedFraction() * (getHeight() - mShapeH))); } }); anim.setRepeatCount(ValueAnimator.INFINITE); anim.setRepeatMode(ValueAnimator.REVERSE); anim.setInterpolator(new AccelerateInterpolator()); //在 REVERSE 時加速也會是 REVERSE anim.start();
//ObjectAnimator ObjectAnimator anim = ObjectAnimator.ofInt(this, "shapeY", 0, (getHeight() - mShapeH)); //與 ValueAnimator 不同,不用 addUpdateListener 去每次設定值,ObjectAnimator 幫我們做好了 anim.setRepeatCount(ValueAnimator.INFINITE); anim.setRepeatMode(ValueAnimator.REVERSE); anim.setInterpolator(new AccelerateInterpolator()); anim.start();
相關資料:
YouTube - DevBytes: Property Animations
YouTube - DevBytes: Bounce Animations
developer.android.com - Property Animation
developer.android.com - ObjectAnimator
developer.android.com - ValueAnimator
沒有留言:
張貼留言