1. 程式人生 > >屬性動畫和檢視動畫

屬性動畫和檢視動畫

安卓中動畫主要包括兩大類:view檢視動畫和property屬性動畫

    而view動畫又分為兩種:Frame逐幀動畫和Tween補間動畫

          Frame逐幀動畫:主要用於簡單的動畫,就像放電影一樣一幀一幀的播放對應的圖片,生成類似於GIF動態圖效果。DrawableAnimation也是指此類動畫

          Tween補間動畫:主要包括四種動畫Alpha透明度,Translate位移,Rotate旋轉,Scale縮放效果

view檢視動畫相比屬性動畫,有一個很大的區別特點:檢視動畫只是顯示位置的變化,view的實際位置並未改變,表現為view移動到其他地方,點選事件仍在原來的地方才能響應。而屬性動畫恰恰相反(注android 3.0 API 11 後才出現的屬性動畫)

Property屬性動畫:

   該動畫有一些相關類組成。

         1.ObjectAnimator :物件動畫執行類。   

         2.ValueAnimator :值動畫執行類,常配合AnimatorUpdateListener使用。          3.PropertyValuesHolder : 屬性儲存器,為兩個執行類提供更新多個屬性的功能。          4.Keyframe :為 PropertyValuesHolder提供多個關鍵幀的操作值。          5.AnimatorSet :一組動畫的執行集合類:設定執行的先後順序,時間等。          6.AnimatorUpdateListener
:動畫更新監聽。          7.AnimatorListener :動畫執行監聽,在動畫開始、重複、結束、取消時進行回撥。          8.AnimatorInflater :載入屬性動畫的xml檔案。          9.TypeEvaluator :型別估值,用於設定複雜的動畫操作屬性的值。          10. TimeInterpolator :時間插值,用於控制動畫執行過程。

1.ObjectAnimator物件動畫執行類
介紹: 1. 通過靜態方法ofInt、ofFloat、ofObject、ofPropertyValuesHolder 獲取類物件。 2. 根據屬性值型別選擇靜態方法,如view的setLeft(int left) 則選用ofInt方法, setY(float y)則選用ofFloat方法。 3. 同ValueAnimator一樣,可以進行串聯式使用,示例如下。
    第一個簡單示例:View的橫向移動    
       // 通過靜態方法構建一個ObjectAnimator物件
       // 設定作用物件、屬性名稱、數值集合
           ObjectAnimator.ofFloat(view, "translationX", 0.0F, 200.0F)
       // 設定執行時間(1000ms)
           .setDuration(1000)
      // 開始動畫
          .start();
   第二個複雜點的示例:View彈性落下然後彈起,執行一次。
     // 修改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的多個屬性,使用起來更加靈活。    第三個示例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多個屬性的動畫
     // 獲取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()方法。 第七個示例:在回撥中手動更新View對應屬性:
            // 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();
第八個示例:在自定義View內部用於引發重繪:
          // 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,僅重寫需要的監聽即可。 第九個示例:
      // 將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語法如下: <setandroid: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>
示例如下:
        // 載入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。 示例:
            // 型別估值 - 拋物線示例
        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                                            @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)。