Android屬性動畫,android屬性
Android屬性動畫(全面詳細、有圖有代碼)
什麼是Android屬性動畫?屬性動畫(Property Animation)系統是一個健壯的動畫架構系統,它可以滿足你大部分動畫需求。不管動畫對象是否已經繪製到螢幕上,你都可以在動畫執行過程中改變它任意的屬性值。一個屬性動畫會在一段特定長度的時間內改變一個屬性(一個對象中的欄位)的值。你可以通過以下幾步定義一個動畫:指定你要執行動畫的屬性,比如動畫對象(View)在螢幕上的位置,指定執行時間長度,指定你希望的屬性的變化值。
以上是官網的介紹翻譯過來的,簡單說就是講這個玩意兒很好用,以後安卓基本動畫就用屬性動畫(Property Animation)就妥妥的啦。本教程有圖也有真相,包教包會,專治各種搞不懂,歡迎拍磚砸場子!
同類技術對比:
a. 漸層動畫支援四種類型:平移(Translate)、旋轉(Rotate)、縮放(Scale)、不透明度(Alpha)。b. 只是顯示的位置變動,View的實際位置未改變,表現為View移動到其他地方,點擊事件仍在原處才能響應。c. 組合使用步驟較複雜。d. View Animation 也是指此動畫。
a. 用於產生連續的Gif。b. DrawableAnimation也是指此動畫。
a. 支援對所有View能更新的屬性的動畫(需要屬性的setXxx()和getXxx())。b. 更改的是View實際的屬性,所以不會影響其在動畫執行後所在位置的正常使用。c. Android3.0 (API11)及以後出現的功能,3.0之前的版本可使用github第三方開源庫nineoldandroids.jar進行支援。
屬性動畫組成部分、相關類介紹:1.ObjectAnimator :對象動畫執行類。2.ValueAnimator :值動畫執行類,常配合AnimatorUpdateListener使用。3.PropertyValuesHolder : 屬性儲存區器,為兩個執行類提供更新多個屬性的功能。4.Keyframe :為 PropertyValuesHolder提供多個主要畫面格的操作值。5.AnimatorSet :一組動畫的執行集合類:設定執行的先後順序,時間等。6.AnimatorUpdateListener :動畫更新監聽。7.AnimatorListener :動畫執行監聽,在動畫開始、重複、結束、取消時進行回調。8.AnimatorInflater :載入屬性動畫的xml檔案。9.TypeEvaluator :類型估值,用於設定複雜的動畫操作屬性的值。10. TimeInterpolator :時間插值,用於控制動畫執行過程。
(以下原始碼:http://pan.baidu.com/s/1mgFXOkK)
1.ObjectAnimator對象動畫執行類
介紹:1. 通過靜態方法ofInt、ofFloat、ofObject、ofPropertyValuesHolder 擷取類對象。2. 根據屬性值類型選擇靜態方法,如view的setLeft(int left) 則選用ofInt方法, setY(float y)則選用ofFloat方法。3. 同ValueAnimator一樣,可以進行串聯式使用,樣本如下。樣本:
// 通過靜態方法構建一個ObjectAnimator對象 // 設定作用對象、屬性名稱、數值集合 ObjectAnimator.ofFloat(view, "translationX", 0.0F, 200.0F) // 設定執行時間(1000ms) .setDuration(1000) // 開始動畫 .start();
// 修改view的y屬性, 從當前位置移動到300.0f ObjectAnimator yBouncer = ObjectAnimator.ofFloat(view, "y", view.getY(), 300.0f); yBouncer.setDuration(1500); // 設定插值器(用於調節動畫執行過程的速度) yBouncer.setInterpolator(new BounceInterpolator()); // 設定重複次數(預設為0,表示不重複執行) yBouncer.setRepeatCount(1); // 設定重複模式(RESTART或REVERSE),重複次數大於0或INFINITE生效 yBouncer.setRepeatMode(ValueAnimator.REVERSE); // 設定動畫開始的延時時間(200ms) yBouncer.setStartDelay(200); // 開始動畫 yBouncer.start();
2.ValueAnimator 值動畫執行類
介紹:1. 構造方法與ObjectAnimator類似。2. 與ObjectAnimator的區別在於ValueAnimator建構函式的參數中不包含動畫“屬性”資訊。3. 優點:結合動畫更新監聽onAnimationUpdate使用,可以在回調中不斷更新View的多個屬性,使用起來更加靈活。樣本:
// 通過靜態方法構建一個ValueAnimator對象 // 設定數值集合 ValueAnimator animator = ValueAnimator.ofFloat(0f, 200.0f); // 設定作用對象 animator.setTarget(view); // 設定執行時間(1000ms) animator.setDuration(1000); // 添加動畫更新監聽 animator.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { // 擷取當前值 Float mValue = (Float) animation.getAnimatedValue(); // 設定橫向位移量 view.setTranslationX(mValue); // 設定縱向位移量 view.setTranslationY(mValue); } }); // 開始動畫 animator.start();
3.PropertyValuesHolder 屬性儲存區器
介紹:為ValueAnimator提供多個操作屬性及相應的執行參數。 樣本:
// 擷取view左邊位置 int left = view.getLeft(); // 擷取view右邊位置 int right = view.getRight(); // 將view左邊增加10像素 PropertyValuesHolder pvhLeft = PropertyValuesHolder.ofInt("left", left, left + 10); // 將view右邊減少10像素 PropertyValuesHolder pvhRight = PropertyValuesHolder.ofInt("right", right, right - 10); // 在X軸縮放從原始比例1f,縮小到最小0f,再放大到原始比例1f PropertyValuesHolder pvhScaleX = PropertyValuesHolder.ofFloat("scaleX", 1f, 0f, 1f); // 在Y軸縮放從原始比例1f,縮小到最小0f,再放大到原始比例1f PropertyValuesHolder pvhScaleY = PropertyValuesHolder.ofFloat("scaleY", 1f, 0f, 1f); // 將PropertyValuesHolder交付給ObjectAnimator進行構建 ObjectAnimator customAnim = ObjectAnimator.ofPropertyValuesHolder(view, pvhLeft, pvhRight, pvhScaleX, pvhScaleY); // 設定執行時間(1000ms) customAnim.setDuration(1000); // 開始動畫 customAnim.start();
4.Keyframe 主要畫面格
介紹:為 PropertyValuesHolder提供主要畫面格的操作值集合。樣本:
- 以下樣本表示該PropertyValuesHolder進行的旋轉(rotation)動畫,在執行時間在0%, 50%, 100%時,其旋轉角度分別為0°, 360°, 0°。動畫執行過程中自動進行補間。表現為自旋360°後再轉回來。
// 設定在動畫開始時,旋轉角度為0度 Keyframe kf0 = Keyframe.ofFloat(0f, 0f); // 設定在動畫執行50%時,旋轉角度為360度 Keyframe kf1 = Keyframe.ofFloat(.5f, 360f); // 設定在動畫結束時,旋轉角度為0度 Keyframe kf2 = Keyframe.ofFloat(1f, 0f); // 使用PropertyValuesHolder進行屬性名稱和值集合的封裝 PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe( "rotation", kf0, kf1, kf2); // 通過ObjectAnimator進行執行 ObjectAnimator.ofPropertyValuesHolder(view, pvhRotation) // 設定執行時間(1000ms) .setDuration(1000) // 開始動畫 .start();
5.AnimatorSet 執行集合類
介紹:1. 為多個屬性動畫提供播放順序控制(注意play,with,after,before的用法)。2. AnimatorSet類與AnimationSet類不能搞混,AnimatorSet在3.0及以上版本中才有。3.0之前的版本可使用第三方開源庫nineoldandroids.jar進行支援,功能使用完全一致。樣本:以下樣本動畫的播放順序為1.播放 bounceAnim;2.同時播放 squashAnim1, squashAnim2,stretchAnim1, stretchAnim2;3.接著播放 bounceBackAnim;4.最後播放 fadeAnim;
AnimatorSet bouncer = new AnimatorSet(); bouncer.play(bounceAnim).before(squashAnim1); bouncer.play(squashAnim1).with(squashAnim2); bouncer.play(squashAnim1).with(stretchAnim1); bouncer.play(squashAnim1).with(stretchAnim2); bouncer.play(bounceBackAnim).after(stretchAnim2); ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f); fadeAnim.setDuration(250); AnimatorSet animatorSet = new AnimatorSet(); animatorSet.play(bouncer).before(fadeAnim); animatorSet.start();
詳細代碼參見:http://developer.android.com/guide/topics/graphics/prop-animation.html
6. AnimatorUpdateListener動畫更新監聽
介紹:1.在動畫執行過程中,每次更新都會調用該回調,可以在該回調中手動更新view的屬性。2.當調用的屬性方法中沒有進行View的重繪時,需要進行手動觸發重繪。設定AnimatorUpdateListener監聽,並在onAnimationUpdate回調中執行View的invalidate()方法。樣本:
// 1. 在回調中手動更新View對應屬性: AnimatorUpdateListener l = new AnimatorUpdateListener() { public void onAnimationUpdate(ValueAnimator animation) { // 當前的分度值範圍為0.0f->1.0f // 分度值是動畫執行的百分比。區別於AnimatedValue。 float fraction = animation.getAnimatedFraction(); // 以下的的效果為 View從完全透明到不透明, view.setAlpha(fraction); // Y方向向下移動300px的距離. view.setTranslationY(fraction * 300.0f); } }; ValueAnimator mAnim = ValueAnimator.ofFloat(0f, 1.0f); mAnim.addUpdateListener(l); mAnim.setDuration(1000); mAnim.start();
// 2. 在自訂View內部用於引發重繪 public class MyAnimationView extends View implements ValueAnimator.AnimatorUpdateListener { public MyAnimationView(Context context) { super(context); } @Override public void onAnimationUpdate(ValueAnimator animation) { // 手動觸發介面重繪 invalidate(); } }
7.AnimatorListener 動畫執行監聽
介紹:1. 實現AnimatorListener中的方法可在動畫執行全程進行其他任務的回調執行。2. 也可以添加AnimatorListener的實作類別AnimatorListenerAdapter,僅重寫需要的監聽即可。樣本:
<span style="font-weight: 700;"> </span>// 將view透明度從當前的1.0f更新為0.5f,在動畫結束時移除該View ObjectAnimator anim = ObjectAnimator.ofFloat(view, "alpha", 0.5f); anim.setDuration(1000); anim.addListener(new AnimatorListener() { @Override public void onAnimationStart(Animator animation) { // 動畫開始時調用 } @Override public void onAnimationRepeat(Animator animation) { // 動畫重複時調用 } @Override public void onAnimationEnd(Animator animation) { // 動畫結束時調用 ViewGroup parent = (ViewGroup) view.getParent(); if (parent != null) parent.removeView(view); } @Override public void onAnimationCancel(Animator animation) { // 動畫取消時調用 } }); anim.start();
8.AnimatorInflater 動畫載入器
介紹:1. 屬性動畫可以通過xml檔案的形式載入。2. set標籤內的animator也可單獨使用。3. XML文法如下:
<set android:ordering=["together" ¦ "sequentially"]> <objectAnimator android:propertyName="string" android:duration="int" android:valueFrom="float¦ int ¦ color" android:valueTo="float¦ int ¦ color" android:startOffset="int" android:repeatCount="int" android:repeatMode=["repeat"¦ "reverse"] android:valueType=["intType"¦ "floatType"]/> <animator android:duration="int" android:valueFrom="float¦ int ¦ color" android:valueTo="float¦ int ¦ color" android:startOffset="int" android:repeatCount="int" android:repeatMode=["repeat"¦ "reverse"] android:valueType=["intType"¦ "floatType"]/> <set> ... </set></set>
樣本:
<span style="font-weight: 700;"> </span> // 載入xml屬性動畫 Animator anim = AnimatorInflater .loadAnimator(this, R.anim.animator_set); anim.setTarget(view); anim.start();
xml檔案:
<?xml version="1.0" encoding="utf-8"?><set> <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" android:duration="1000" android:valueTo="200" android:valueType="floatType" android:propertyName="x" android:repeatCount="1" android:repeatMode="reverse"/> <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" android:duration="1000" android:valueTo="400" android:valueType="floatType" android:propertyName="y" android:repeatCount="1" android:repeatMode="reverse"/></set>
9.TypeEvaluator 類型估值
介紹:1. TypeEvaluator可傳入參數值的類型(本例為PointF)。2. 重寫函數public T evaluate(floatfraction, T startValue, T endValue);實現不同需求值的計算。3. 注意fraction的使用,fraction是從開始到結束的分度值0.0 -> 1.0。樣本:
<span style="font-weight: 700;"> </span>// 類型估值 - 拋物線樣本 TypeEvaluator<PointF> typeEvaluator = new TypeEvaluator<PointF>() { @Override public PointF evaluate(float fraction, PointF startValue, PointF endValue) { float time = fraction * 3; Log.e(TAG, time + ""); // x方向200px/s ,y方向0.5 * 200 * t * t PointF point = new PointF(); point.x = 120 * time; point.y = 0.5f * 200 * time * time; return point; } }; ValueAnimator valueAnimator = ValueAnimator.ofObject(typeEvaluator, new PointF(0, 0)); valueAnimator.setInterpolator(new LinearInterpolator()); valueAnimator.setDuration(3000); valueAnimator.start(); valueAnimator.addUpdateListener(new AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { PointF point = (PointF) animation.getAnimatedValue(); view.setX(point.x); view.setY(point.y); } });
10. TimeInterpolator 時間插值器
1. 幾種常見的插值器:
| Interpolator對象 |
資源ID |
功能作用 |
| 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/cycle_interpolator |
周期運動 |
| DecelerateInterpolator |
@android:anim/decelerate_interpolator |
減速 |
| LinearInterpolator |
@android:anim/linear_interpolator |
勻速 |
| OvershootInterpolator |
@android:anim/overshoot_interpolator |
快速到達終點並超出一小步最後回到終點 |
2. 自訂插值器a.實現Interpolator(TimeInterpolator)介面;b.重寫介面函數float getInterpolation(floatinput)。