1. 程式人生 > >Android 屬性動畫ObjectAnimator和ValueAnimator講解

Android 屬性動畫ObjectAnimator和ValueAnimator講解

區別:

  ObjectAnimator 是直接對某個view進行更改。

  ValueAnimator 根據 TimeInterpolator 在不斷產生相應的資料,來傳進view  ,view自己做改變。

介紹:

  1.屬性動畫是通過改變某個控制元件的屬性值來創造動畫,比如在規定的時間內改變某個控制元件的X座標,則會產生一個平移的動畫效果。

  2.堅持使用屬性動畫和幀動畫,而不要使用補間動畫,補間動畫會造成控制元件移動到目的地但是控制元件的熱點(產生事件的範圍)仍然在原地

  3.屬性動畫幾乎可以產生一切你想要的效果,一般在插入動畫時,預設為勻速從起點到終點,可以通過插值改變從起點到終點的效果

  4.屬性動畫分為ObjectAnimator和ValueAnimator,其中ObjectAnimator是繼承於ValueAnimator

ObjectAnimator:

  對控制元件的某個屬性執行一次動畫。

    1.通過 ObjectAnimator.ofFloat(<控制元件控制代碼>,<控制元件屬性>,<從什麼float值>,<到什麼float值>).setDuration(1000).start();來建立一次動畫。

      其中ofFloat是根據後面屬性值的型別設定的。如果是整型,可以設定為ofInt

      如果有多個這樣的,一次執行並不會分先後順序,是一起執行,包括對同一控制元件的操作,因為設定動畫並不會阻礙主執行緒。

    2.為了是屬性複用化,節省程式碼操作,我們把對控制元件的一組屬性的一次操作提取出來稱為一個屬性操作集,比如,我想對控制元件進行平移和旋轉,我們可以先把

      平移和旋轉(以及他們操作的數值)單獨拿出來作為一個屬性,然後控制元件呼叫這個動畫集,就可以實現無論什麼控制元件都可以公用這個屬性動畫。

      操作:通過 PropertyValuesHolder pro = PropertyValuesHolder.ofFloat("translationX",0F,100F);封裝平移X的動畫

          然後PropertyValuesHolder pro2 = PropertyValuesHolder.ofFloat("rotation",0F,360F);封裝旋轉360的動畫

          最後通過ObjectAnimator.ofPropertyValuesHolder(<控制元件控制代碼>,pro,pro1,pro2);來為某個控制元件設定以上動畫,其他控制元件也可

          複用以上程式碼

    3.以上只是說明了對控制元件的多個屬性一次操作,並沒有說明控制元件屬性改變的先後順序,以及對多個控制元件一起操作。這是我們引入了AnimatorSet

      先例項化這個屬性動畫集合 AnimatorSet set = new AnimatorSet().

      通過set.play(<animator1>).with(<animator2>);來表示讓Animator1和Animator2一起執行,

      通過set.play(<animator1>).after(<animator2>)來表示讓Animator1在Animator2後執行

      通過set.play(<animator1>).before(<animator2>)來表示讓Animator1在Animator2之前執行、

      其中Animator1和Animator2都可以填充ObjectAnimator。這樣就可以對某個控制元件的先後順序和對多個控制元件的動畫配合起到至關作用

    4.以上所表示的動畫都是將某個屬性從一個值勻速的改變成另一個值。

      我們可以用set.setInterpolator();來設定一個改變的效果。裡面只要new 一個Interpolator方可,

      比如:set.setInterpolator(new AccelerateInterpolator());

ValueAnimator:

    1.ValueAnimator並不會改變屬性的大小,他只是在一段時間生成某些值,比如上面的ofFloat中設定了從0F,100F,並設定時間為1000

      則ValueAnimator的作用就是在1000中勻速生成0F到100F的值,然後再為控制元件在1000中為控制元件的屬性設上不同值,這就是動畫的原理

      我們可以通過執行緒和執行緒休眠來設定動畫,但是這樣太佔用資源,所以我們不建議使用執行緒而使用Animator

    2.我們可以獲取1000內產生的值   

        ValueAnimator value = ValueAnimator.ofFloat(0F,100F);
        value.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
         @Override
         public void onAnimationUpdate(ValueAnimator animation) {
           float value = (float) animation.getAnimatedValue();
         }
        });
      這樣就可以獲取,我們可以通過設定一個計時器,就是每秒就為控制元件設定獲取到的值
    3.我們可以自定義獲取的值(通過泛型),這樣就顯得更加靈活,可以在一段時間內得到我們想要的值
       
value.ofObject(new TypeEvaluator<Float>() {
        @Override
         public Float evaluate(float fraction, Float startValue, Float endValue) {
            return null; // 這裡可以自己自定義 返回的資料  , fraction 是0到1之間的數 這裡確定的是每一幀的資料
          }
     },0F,100F);


 

 

     new TypeEvaluator<Boolean>() {

            @Override
            public Boolean evaluate(float fraction, Boolean startValue, Boolean endValue) {
                return null;
            }

        };

 

 

    此時我們可以反回任意的值,其中fraction是從0到1,相當於進度的百分比 我們可以通過條件語句判斷來反回真正需要反回的值,然後通過addUpdateListener    就可以很靈活的實現各種值的返回

    4. 我們還可以控制動畫的執行速度 運用插值器
    
     mAnimator.setInterpolator(new Interpolator() {
            @Override
            public float getInterpolation(float input) {
                return 0;//  這裡 input與 return 都是0到1之間的數  , 兩者之間我們可以編寫 y = f(x) 的函式,斜率變化 就是我們動畫的播放速率變化
            }
        });

 常見插值器:

    AccelerateDecelerateInterpolator   在動畫開始與介紹的地方速率改變比較慢,在中間的時候加速
    AccelerateInterpolator                     在動畫開始的地方速率改變比較慢,然後開始加速
    AnticipateInterpolator                      開始的時候向後然後向前甩
    AnticipateOvershootInterpolator     開始的時候向後然後向前甩一定值後返回最後的值
    BounceInterpolator                          動畫結束的時候彈起
    CycleInterpolator                             動畫迴圈播放特定的次數,速率改變沿著正弦曲線
    DecelerateInterpolator                    在動畫開始的地方快然後慢
    LinearInterpolator                            以常量速率改變
    OvershootInterpolator                      向前甩一定值後再回到原來位置