Android動畫

Animation


  • Animation類是所有動畫(scale、alpha、translate、rotate)的基類,以下是關于 Animation 的屬性及意義:
  • android:duration 動畫持續時間,以毫秒為單位
  • android:fillAfter 如果設置為true,控件動畫結束時,將保持動畫最后時的狀態
  • android:fillBefore 如果設置為true,控件動畫結束時,還原到開始動畫前的狀態
  • android:fillEnabled 與android:fillBefore 效果相同,都是在動畫結束時,將控件還原到初始化狀態
  • android:repeatCount 重復次數
  • android:repeatMode 重復類型,有reverse和restart兩個值,reverse表示倒序回放,restart表示重新放一遍,必須與repeatCount一起使用才能看到效果。因為這里的意義是重復的類型,即回放時的動作。
  • android:interpolator 設定插值器,其實就是指定的動作效果,比如彈跳效果等
scale
  • scale標簽是縮放動畫,可以實現動態調控件尺寸的效果,有下面幾個屬性:
  • android:fromXScale 起始的X方向上相對自身的縮放比例,浮點值,比如1.0代表自身無變化,0.5代表起始時縮小一倍,2.0代表放大一倍;
  • android:toXScale 結尾的X方向上相對自身的縮放比例,浮點值;
  • android:fromYScale 起始的Y方向上相對自身的縮放比例,浮點值,
  • android:toYScale 結尾的Y方向上相對自身的縮放比例,浮點值;
  • android:pivotX 縮放起點X軸坐標,可以是數值、百分數、百分數p 三種樣式,比如 50、50%、50%p,當為數值時,表示在當前View的左上角,即原點處加上50px,做為起始縮放點;如果是50%,表示在當前控件的左上角加上自己寬度的50%做為起始點;如果是50%p,那么就是表示在當前的左上角加上父控件寬度的50%做為起始點x軸坐標。
  • android:pivotY 縮放起點Y軸坐標,取值及意義跟android:pivotX一樣。
alpha
  • alpha是透明動畫,調節控件的透明度,屬性如下:
  • android:fromAlpha 動畫開始的透明度,從0.0 --1.0 ,0.0表示全透明,1.0表示完全不透明
  • android:toAlpha 動畫結束時的透明度,也是從0.0 --1.0 ,0.0表示全透明,1.0表示完全不透明
rotate
  • rotate是旋轉動畫,控制控件在平面上的旋轉角度
  • android:fromDegrees 開始旋轉的角度位置,正值代表順時針方向度數,負值代碼逆時針方向度數
  • android:toDegrees 結束時旋轉到的角度位置,正值代表順時針方向度數,負值代碼逆時針方向度數
  • android:pivotX 旋轉中點X坐標
  • android:pivotY 旋轉中點Y坐標
translate
  • translate是平移動畫,控制控件水平或垂直移動
  • android:fromXDelta 起始點X軸坐標,可以是數值、百分數、百分數p 三種樣式
  • android:fromYDelta 起始點Y軸從標
  • android:toXDelta 結束點X軸坐標
  • android:toYDelta 結束點Y軸坐標
set
  • set定義動畫的集合,可以將多個動畫打包執行,在XML中set的定義方式如下:
    <?xml version="1.0" encoding="utf-8"?>
    <set xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="3000"
    android:fillAfter="true">

         <alpha   
             android:fromAlpha="0.0"  
             android:toAlpha="1.0"/>  
    
         <scale  
             android:fromXScale="0.0"  
             android:toXScale="1.4"  
             android:fromYScale="0.0"  
             android:toYScale="1.4"  
             android:pivotX="50%"  
             android:pivotY="50%"/>  
    
        <rotate  
             android:fromDegrees="0"  
             android:toDegrees="720"  
             android:pivotX="50%"  
            android:pivotY="50%"/>  
       
    </set> 
    
執行動畫(XML)
  • 在項目的 res -> anim下定義動畫(xxx.xml)
  • 在代碼中加載動畫,并讓目標控件執行
    Animation anim = AnimationUtils.loadAnimation(this, R.anim.xxx);
    imag.startAnimation(anim);
Interpolator插值器
  • Interpolator賦予動畫一些特性,它指定了動畫變化的特征,系統提供的Interpolator如下:
    • AccelerateDecelerateInterpolator 在動畫開始與介紹的地方速率改變比較慢,在中間的時候加速
  • AccelerateInterpolator 在動畫開始的地方速率改變比較慢,然后開始加速
  • AnticipateInterpolator 開始的時候向后然后向前甩
  • AnticipateOvershootInterpolator 開始的時候向后然后向前甩一定值后返回最后的值
  • BounceInterpolator 動畫結束的時候彈起
  • CycleInterpolator 動畫循環播放特定的次數,速率改變沿著正弦曲線
  • DecelerateInterpolator 在動畫開始的地方快然后慢
  • LinearInterpolator 以常量速率改變
  • OvershootInterpolator 向前甩一定值后再回到原來位置
  • xml動畫中添加Interpolator
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
代碼生成動畫

前面介紹了通過xml定義動畫,動畫集合,插值器等,其實通過代碼也可以做到.

  • ScaleAnimation
    ScaleAnimation scaleAnim = new ScaleAnimation(0.0f,1.4f,0.0f,1.4f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
    scaleAnim.setDuration(700);

    //它相當于在xml如下定義
     <?xml version="1.0" encoding="utf-8"?>  
     <scale xmlns:android="http://schemas.android.com/apk/res/android"                                                                   
         android:fromXScale="0.0"  
         android:toXScale="1.4"  
         android:fromYScale="0.0"  
         android:toYScale="1.4"  
         android:pivotX="50"  
         android:pivotY="50"  
         android:duration="700" />    
    
  • AlphaAnimation
    AlphaAnimation alphaAnim = new AlphaAnimation(1.0f,0.1f);
    alphaAnim.setDuration(3000);
    alphaAnim.setFillBefore(true);

    //對應xml屬性如下:
    //android:fromAlpha="1.0"  
    //android:toAlpha="0.1"  
    //android:duration="3000"  
    //android:fillBefore="true"    
    
  • RotateAnimation
    RotateAnimation rotateAnim = new RotateAnimation(0, -650, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
    rotateAnim.setDuration(3000);
    rotateAnim.setFillAfter(true);

    //對應xml屬性如下:
    //android:fromDegrees="0"  
    //android:toDegrees="-650"  
    //android:pivotX="50%"  
    //android:pivotY="50%"  
    //android:duration="3000"  
    //android:fillAfter="true"
    
  • TranslateAnimation
    TranslateAnimation translateAnim = new TranslateAnimation(Animation.ABSOLUTE, 0, Animation.ABSOLUTE, -80,
    Animation.ABSOLUTE, 0, Animation.ABSOLUTE, -80);
    translateAnim.setDuration(2000);
    translateAnim.setFillBefore(true);

    //對應xml屬性:
    //android:fromXDelta="0"   
    //android:toXDelta="-80"  
    //android:fromYDelta="0"  
    //android:toYDelta="-80"  
    //android:duration="2000"  
    //android:fillBefore="true"
    
  • AnimationSet
    AlphaAnimation alphaAnim = new AlphaAnimation(1.0f,0.1f);
    ScaleAnimation scaleAnim = new ScaleAnimation(0.0f,1.4f,0.0f,1.4f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
    RotateAnimation rotateAnim = new RotateAnimation(0, 720, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);

    AnimationSet setAnim=new AnimationSet(true);  
    setAnim.addAnimation(alphaAnim);  
    setAnim.addAnimation(scaleAnim);  
    setAnim.addAnimation(rotateAnim);   
    setAnim.setDuration(3000);  
    
  • Interpolater
    ScaleAnimation interpolateScaleAnim=new ScaleAnimation(0.0f,1.4f,0.0f,1.4f,Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
    interpolateScaleAnim.setInterpolator(new BounceInterpolator());
    interpolateScaleAnim.setDuration(3000);

Property Animator(屬性動畫)


ValueAnimator
  • ValueAnimator只負責對指定的數字區間進行動畫運算

  • 我們需要對運算過程進行監聽,然后自己對控件做動畫操作

  • ValueAnimator的構件方法
    public static ValueAnimator ofInt(int... values)
    public static ValueAnimator ofFloat(float... values)

     //他們的參數類型都是可變參數長參數,所以我們可以傳入任何數量的值;傳進去的值列表,就表示動畫時的變化范圍;
     //比如ofInt(2,90,45)就表示從數值2變化到數字90再變化到數字45;所以我們傳進去的數字越多,動畫變化就越復雜。
     //從參數類型也可以看出ofInt與ofFloat的唯一區別就是傳入的數字類型不一樣,
     //ofInt需要傳入Int類型的參數,而ofFloat則表示需要傳入Float類型的參數。 
    
  • ValueAnimator的常用函數
    //設置動畫時長,單位是毫秒
    ValueAnimator setDuration(long duration)
    //獲取ValueAnimator在運動時,當前運動點的值
    Object getAnimatedValue();
    //開始動畫
    void start()
    //設置循環次數,設置為INFINITE表示無限循環
    void setRepeatCount(int value)
    //設置循環模式 value取值有RESTART,REVERSE,
    void setRepeatMode(int value)
    //取消動畫
    void cancel()
    //設置插值器
    void setInterpolator(TimeInterpolator value)
    //延時多久時間開始,單位是毫秒
    void setStartDelay(long startDelay)
    //完全克隆一個ValueAnimator實例,包括它所有的設置以及所有對監聽器代碼的處理
    ValueAnimator clone()

  • 舉例說明ValueAnimator的使用方式
    ValueAnimator animator = ValueAnimator.ofFloat(0f,400f,50f,300f);
    animator.setDuration(3000);
    //監聽動畫變化時的實時值
    animator.addUpdateListener(
    new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
    //獲取當前的值(這里傳入的是float,所以強轉為Float)
    Float curValueFloat = (Float)animation.getAnimatedValue();
    int curValue = curValueFloat.intValue();
    //跟隨值的變化,而改變控件的屬性
    tv.layout(curValue,curValue,curValue+tv.getWidth(),
    curValue+tv.getHeight());
    }
    });
    animator.start();

  • ValueAnimator 監聽
    /**
    * 監聽器一:監聽動畫變化時的實時值
    */
    public static interface AnimatorUpdateListener {
    void onAnimationUpdate(ValueAnimator animation);
    }
    //添加方法為:
    //public void addUpdateListener(AnimatorUpdateListener listener)
    //移除的方法
    //void removeUpdateListener(AnimatorUpdateListener listener);
    //void removeAllUpdateListeners();

    /** 
     * 監聽器二:監聽動畫變化時四個狀態 
     */  
     public static interface AnimatorListener {  
       void onAnimationStart(Animator animation);  
       void onAnimationEnd(Animator animation);  
       void onAnimationCancel(Animator animation);  
       void onAnimationRepeat(Animator animation);  
    }  
    //添加方法為:
    //public void addListener(AnimatorListener listener)  
    //void removeListener(AnimatorListener listener);  
    //void removeAllListeners(); 
    
  • 自定義Interpolator
    public class MyInterpolator implements Interpolator {

       public LinearInterpolator() {  
       }  
    
       public LinearInterpolator(Context context, AttributeSet attrs) {  
       }  
    
       public float getInterpolation(float input) { 
          // input表示動畫的時間進度,范圍是0到1,隨著動畫的執行勻速增長
          // 返回值表示動畫的實際進度,是關于input的一維函數
          // 當前的值 = start + (end- start)* 動畫進度
          return input;  
       }  
    }  
    
  • Evaluator

    • 插值器的進度,是如何轉換為動畫實際的值?
      Evaluator就是將動畫進度轉換為實際值的東西,它定義了轉換的規則.
    • FloatEvaluator 和 IntEvaluator分別對應 ofFloat() 和 ofInt()
      當我們定義動畫的時候,如果不顯示的添加Evaluator,則使用默認的Evaluator
      public class IntEvaluator implements TypeEvaluator<Integer> {
      public Integer evaluate(float fraction,
      Integer startValue, Integer endValue) {
      int startInt = startValue;
      //當前的值 = start + (end- start)* 動畫進度
      //可以自定義規則
      return (int)(startInt + fraction * (endValue - startInt));
      }
      }
  • ArgbEvaluator (用于處理顏色值過渡轉換)
    public class ArgbEvaluator implements TypeEvaluator {
    public Object evaluate(float fraction,
    Object startValue, Object endValue) {
    int startInt = (Integer) startValue;
    int startA = (startInt >> 24);
    int startR = (startInt >> 16) & 0xff;
    int startG = (startInt >> 8) & 0xff;
    int startB = startInt & 0xff;

            int endInt = (Integer) endValue;  
            int endA = (endInt >> 24);  
            int endR = (endInt >> 16) & 0xff;  
            int endG = (endInt >> 8) & 0xff;  
            int endB = endInt & 0xff;  
    
            return (int)((startA + (int)(fraction * (endA - startA))) << 24) |  
               (int)((startR + (int)(fraction * (endR - startR))) << 16) |  
               (int)((startG + (int)(fraction * (endG - startG))) << 8) |  
               (int)((startB + (int)(fraction * (endB - startB))));  
          }  
     }  
    
     ...
     //使用例子
      ValueAnimator animator = ValueAnimator.ofInt(0xffffff00,0xff0000ff);                                                                    
      animator.setEvaluator(new ArgbEvaluator());  
      animator.setDuration(3000);  
    
      animator.addUpdateListener(
              new ValueAnimator.AnimatorUpdateListener() {  
         @Override  
         public void onAnimationUpdate(ValueAnimator animation) {  
             int curValue = (int)animation.getAnimatedValue();  
             tv.setBackgroundColor(curValue);  
         }  
      });  
      animator.start();  
    
  • ofObject()
    public static ValueAnimator ofObject(TypeEvaluator evaluator, Object... values);
    //ofObject相對于ofInt和ofFloat自由度更大些,相應也更復雜點.個人認為ofObject使用的機會不多,所以簡單列舉一個例子說明它的用法

      ValueAnimator animator = ValueAnimator.ofObject(new CharEvaluator(),new Character('A'),new Character('Z'));                                                                                    
      animator.addUpdateListener(
              new ValueAnimator.AnimatorUpdateListener() {  
        @Override  
        public void onAnimationUpdate(ValueAnimator animation) {  
               char text = (char)animation.getAnimatedValue();  
              tv.setText(String.valueOf(text));  
        }  
      });  
      animator.setDuration(10000);  
      animator.setInterpolator(new AccelerateInterpolator());  
      animator.start();  
    
      //... 自定義Evaluator
      
      public class CharEvaluator implements TypeEvaluator<Character> {  
           @Override  
           public Character evaluate(float fraction,
                        Character startValue, Character endValue) {  
                int startInt  = (int)startValue;  
                int endInt = (int)endValue;  
                int curInt = (int)(startInt + fraction *(endInt - startInt));  
                char result = (char)curInt;  
                return result;  
            }  
       }  
    
ObjectAnimator
  • ValueAnimator使用相對比較麻煩,谷歌在ValueAnimator的基礎上派生了ObjectAnimator,所以ObjectAnimator可以視為ValueAnimator的封裝,使用起來更簡單.
    public static ObjectAnimator ofInt(Object target, String propertyName, int... values)
    public static ObjectAnimator ofFloat(Object target, String propertyName, float... values)

     ...
     //以下是透明,旋轉,位移,縮放動畫的定義
     ObjectAnimator animator =  ObjectAnimator.ofFloat(tv,"alpha",1,0,1);  
     ObjectAnimator animator = ObjectAnimator.ofFloat(tv,"rotation",0,180,0);   
     ObjectAnimator animator = ObjectAnimator.ofFloat(tv,"rotationX",0,270,0);
     ObjectAnimator animator = ObjectAnimator.ofFloat(tv,"rotationY",0,180,0);
     ObjectAnimator animator = ObjectAnimator.ofFloat(tv, "translationX", 0, 200,-200,0);
     ObjectAnimator animator = ObjectAnimator.ofFloat(tv, "translationY", 0, 200,-100,0);
     ObjectAnimator animator = ObjectAnimator.ofFloat(tv, "scaleX", 0, 3, 1); 
     ObjectAnimator animator = ObjectAnimator.ofFloat(tv, "scaleY", 0, 3, 1);
    
  • why ? 為什么通過一段字符串,就可以執行指定的動畫?

    • 其實上面這些屬性,都有其對應的set函數:
      • setAlpha()
      • setRotation() / setRotationY() / setRotationX()
      • setTranslationY() / setTranslationX()
      • setScaleX() / setScaleY()
        當我們使用以上方式定義屬性動畫時,系統會拼接出目標控件對應的set函數,然后通過反射執行.
        依次類推,只要控件有某一set函數,我們就可以定義對應的動畫,比如:
        //setBackgrounColor()
        ObjectAnimator animator = ObjectAnimator.ofInt(tv, "BackgroundColor", 0xffff00ff, 0xffffff00, 0xffff00ff);
        animator.setDuration(8000);
        animator.setEvaluator(new ArgbEvaluator());
        animator.start();
        進一步,自定義控件的時候,我們可以自定義set函數,都可以使用對應的動畫
  • 因為ObjectAnimator派生自ValueAnimator,所以ValueAnimator其它的函數,它都可以使用,這里不再敘述

  • 屬性的get函數又有何作用呢 ?
    我們已經知道屬性的set函數的作用,那么對應的get函數有沒有什么特殊的作用呢?
    有,OberjectAnimator的構件方法,所需的值都是可變參數,如果只傳入一個值呢?動畫該怎么執行?
    當只有一個值的時候,這個值將是動畫的結束值,而開始值,則由相應的get函數返回

  • PropertyValuesHolder
    PropertyValuesHolder也可以用來構造動畫,事實上,前面我們講的動畫的構造,最終都是通過PropertyValuesHolder完成,并且PropertyValuesHolder可以讓多個動畫效果一起執行,先看下幾個系統的函數:
    // ObjectAnimator
    public static ObjectAnimator ofPropertyValuesHolder(Object target,PropertyValuesHolder... values)
    // PropertyValuesHolder
    public static PropertyValuesHolder ofFloat(String propertyName, float... values)
    public static PropertyValuesHolder ofInt(String propertyName, int... values)
    public static PropertyValuesHolder ofObject(String propertyName, TypeEvaluator evaluator,Object... values)
    public static PropertyValuesHolder ofKeyframe(String propertyName, Keyframe... values)

    // 其實已經很明顯了,我們可以使用PropertyValuesHolder 構建具體的動畫效果, 
    //然后使用 ObjectAnimator 的 ofPropertyValuesHolder函數將一個或多個PropertyValuesHolder 打包創建為動畫對象
    //以下是 使用PropertyValuesHolder 創建動畫的例子:
    PropertyValuesHolder rotationHolder = PropertyValuesHolder.ofFloat("Rotation", 60f, -60f, 40f, -40f, -20f, 20f, 10f, -10f, 0f);  
    PropertyValuesHolder colorHolder = PropertyValuesHolder.ofInt("BackgroundColor", 0xffffffff, 0xffff00ff, 0xffffff00, 0xffffffff);  
    ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(mTextView, rotationHolder, colorHolder);  
    animator.setDuration(3000);  
    animator.setInterpolator(new AccelerateInterpolator());  
    animator.start(); 
    
    //關于ofObject的使用方與ObjectAnimator的ofObject大同小異...
    //ofKeyframe會在下面具體講解
    
  • Keyframe(關鍵幀)
    之前我們知道,通過插值器和Evaluator可以控制動畫的變化速率,但如果要實現更復雜的效果,就需要定義更復雜的公式.Keyframe同樣可以控制動畫的速率,使用起來也更簡單.在講自定義插值器的時候,曾提到過,動畫的進度在0~1之間,而Keyframe可以讓我們指定動畫在某一進度點上的值,通過這種方式,我們可以更靈活,更簡單的控制動畫的速率.
    //動畫開始的值為 0
    Keyframe frame0 = Keyframe.ofFloat(0f, 0);
    //動畫進度為0.1的時候,值為 -20
    Keyframe frame1 = Keyframe.ofFloat(0.1f, -20f);
    //動畫結束的時候,值為 0
    Keyframe frame2 = Keyframe.ofFloat(1, 0);
    //通過 Keyframe 構建 PropertyValuesHolder
    PropertyValuesHolder frameHolder = PropertyValuesHolder.ofKeyframe("rotation",frame0,frame1,frame2);
    Animator animator = ObjectAnimator.ofPropertyValuesHolder(mImage,frameHolder);
    animator.setDuration(1000);
    animator.start();

    //使用Keyframe,每兩幀之間默認勻速執行,即線性插值器,更強大的是,我們可以給Keyframe指定插值器,
    //如果給某個Keyframe設置了插值器,那么從前一幀到這一幀的動畫會按插值器執行
    public void setInterpolator(TimeInterpolator interpolator)
    
    //同樣的,Keyframe的構建方式也有以下幾種
    public static Keyframe ofInt(float fraction, int value)  
    public static Keyframe ofFloat(float fraction, float value)
    public static Keyframe ofObject(float fraction, Object value)
    
    //***需要強調的是,使用Keyframe的時候,最少需要兩幀,否則會報錯
    //***另外第一幀是動畫的開始,最后一幀是動畫的結束
    
  • AnimatorSet
    顧名思義,AnimatorSet可以聯合多個動畫一起執行:
    //多個動畫順序執行
    public void playSequentially(Animator... items);
    public void playSequentially(List<Animator> items);
    //多個動畫同時執行
    public void playTogether(Animator... items);
    public void playTogether(Collection<Animator> items);

    //以上方式都比較簡單, 我們可以使用AnimatorSet.Builder實現更具體的控制,比如指定動畫的執行順序
    // 執行動畫
    public Builder after(Animator aim)
    //和前面動畫一起執行
    public Builder with(Animator anim)
    //先執行前面的動畫,再執行這個動畫
    public Builder before(Animator anim)
    //先執行這個動畫,再執行前面的動畫
    public Builder after(Animator anim)
    
    //示例如下
    ObjectAnimator tv1BgAnimator = ObjectAnimator.ofInt(mTv1, "BackgroundColor", 0xffff00ff, 0xffffff00, 0xffff00ff);
    ObjectAnimator tv1TranslateY = ObjectAnimator.ofFloat(mTv1, "translationY", 0, 400, 0);
    ObjectAnimator tv2TranslateY = ObjectAnimator.ofFloat(mTv2, "translationY", 0, 400, 0);
    AnimatorSet animatorSet = new AnimatorSet();
    animatorSet.play(tv1TranslateY).with(tv2TranslateY).after(tv1BgAnimator);
    animatorSet.setDuration(2000);
    animatorSet.start();
    
  • AnimatorSet 可以通過*addListener(AnimatorListener listener) *監聽其狀態的變化

  • 需要注意的是,某些屬性可以通過AnimatorSet統一設置,比如: 動畫時長,重復次數等.并且如果統一設置了這些屬性,那么針對單個動畫的設置將無效.

  • 使用XML定義屬性動畫

    • 在xml中對應animator總共有三個標簽,分別是

<animator /> 對應ValueAnimator
<objectAnimator /> 對應ObjectAnimator
<set /> 對應AnimatorSet

  • animator (以下是animator完整的字段,及對應的值類型)
    <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"]
    android:interpolator=["@android:interpolator/XXX"]/>

    • android:duration:每次動畫播放的時長
    • android:valueFrom:初始動化值;取值范圍為float,int和color,如果取值為float對應的值樣式應該為89.0,取值為Int時,對應的值樣式為:89;當取值為clolor時,對應的值樣式為 #333333;
    • android:valueTo:動畫結束值;取值范圍同樣是float,int和color這三種類型的值;
    • android:startOffset:動畫激活延時;對應代碼中的startDelay(long delay)函數;
    • android:repeatCount:動畫重復次數
    • android:repeatMode:動畫重復模式,取值為repeat和reverse;repeat表示正序重播,reverse表示倒序重播
    • android:valueType:表示參數值類型,取值為intType和floatType;與android:valueFrom、android:valueTo相對應。如果這里的取值為intType,那么android:valueFrom、android:valueTo的值也就要對應的是int類型的數值。如果這里的數值是floatType,那么android:valueFrom、android:valueTo的值也要對應的設置為float類型的值。非常注意的是,如果android:valueFrom、android:valueTo的值設置為color類型的值,那么不需要設置這個參數;
    • android:interpolator:設置加速器
  • objectAnimator
    objectAnimator對比animator多了一條屬性
    android:propertyName="string"

    • android:propertyName:對應屬性名,即ObjectAnimator所需要操作的屬性名
  • set(set標簽只有一條屬性)
    <set android:ordering=["together" | "sequentially"]>

    • android:ordering:表示動畫開始順序。together表示同時開始動畫,sequentially表示逐個開始動畫
  • 加載XML里定義的動畫
    ValueAnimator valueAnimator = (ValueAnimator) AnimatorInflater.loadAnimator(context,R.animator.animator);
    valueAnimator.start();

     ObjectAnimator animator = (ObjectAnimator) AnimatorInflater.loadAnimator(MyActivity.this, R.animator.object_animator);
     animator.setTarget(mTv1);
     animator.start();
    
     AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(MyActivity.this, R.animator.set_animator);
     set.setTarget(mTv1);
     set.start();
    
布局動畫

LayoutAnimation
  1. XML實現
    <?xml version="1.0" encoding="utf-8"?>
    <layoutAnimation
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:delay="1"
    android:animationOrder="normal"
    android:animation="@anim/slide_in_left"/>

    ...
    
    <ListView android:id="@+id/listview" 
            android:layout_width="match_parent" 
            android:layout_height="match_parent" 
            android:layoutAnimation="@anim/layout_animation" />
    
  2. 代碼實現
    //得到一個LayoutAnimationController對象;
    LayoutAnimationController controller = new LayoutAnimationController(animation);
    //設置控件顯示的順序;
    controller.setOrder(LayoutAnimationController.ORDER_REVERSE);
    //設置控件顯示間隔時間;
    controller.setDelay(0.3f);
    //為ListView設置LayoutAnimationController屬性;
    mListView.setLayoutAnimation(controller);
    mListView.startLayoutAnimation();

  3. 各字段解釋
    delay:指每個Item的動畫開始延時,取值是android:animation所指定動畫時長的倍數,取值類型可以是float類型,也可以是百分數,默認是0.5;比如我們這里指定的動畫是@anim/slide_in_left,而在slide_in_left.xml中指定android:duration=”1000”,即單次動畫的時長是1000毫秒,而我們在這里的指定android:delay=”1”,即一個Item的動畫會在上一個item動畫完成后延時單次動畫時長的一倍時間開始,即延時1000毫秒后開始。
    animationOrder:指viewGroup中的控件動畫開始順序,取值有normal(正序)、reverse(倒序)、random(隨機)
    animation:指定每個item入場所要應用的動畫。僅能指定res/aim文件夾下的animation定義的動畫,不可使用animator動畫。

GridLayoutAnimation
  1. XML實現
    <?xml version="1.0" encoding="utf-8"?>
    <gridLayoutAnimation
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:rowDelay="75%"
    android:columnDelay="60%"
    android:directionPriority="none"
    android:direction="bottom_to_top|right_to_left"
    android:animation="@android:anim/slide_in_left"/>

    ***
    
    <GridView android:id="@+id/grid" 
          android:layout_width="match_parent" 
          android:layout_height="match_parent" 
          android:columnWidth="60dp" 
          android:gravity="center" 
          android:horizontalSpacing="10dp"           
          android:layoutAnimation="@anim/gride_animation"  
          android:numColumns="auto_fit" 
          android:stretchMode="columnWidth" 
          android:verticalSpacing="10dp"/>
    
  2. 代碼實現
    GridLayoutAnimationController controller = new GridLayoutAnimationController(animation);
    controller.setColumnDelay(0.75f);
    controller.setRowDelay(0.5f);
    controller.setDirection(GridLayoutAnimationController.DIRECTION_BOTTOM_TO_TOP|GridLayoutAnimationController.DIRECTION_LEFT_TO_RIGHT);
    controller.setDirectionPriority(GridLayoutAnimationController.PRIORITY_NONE);
    grid.setLayoutAnimation(controller);
    grid.startLayoutAnimation();

  3. 各屬性解釋
    rowDelay:每一行動畫開始的延遲。與LayoutAnimation一樣,可以取百分數,也可以取浮點數。取值意義為,當前android:animation所指動畫時長的倍數。 columnDelay:每一列動畫開始的延遲。取值類型及意義與rowDelay相同。 directionPriority:方向優先級。取值為row,collumn,none,意義分別為:行優先,列優先,和無優先級(同時進行);
    direction:gridview動畫方向。 取值有四個:
    *left_to_right:列,從左向右開始動畫
    right_to_left :列,從右向左開始動畫
    top_to_bottom:行,從上向下開始動畫
    bottom_to_top:行,從下向上開始動畫 *
    這四個值之間可以通過“|”連接,從而可以取多個值。
    很顯然left_to_right和right_to_left是互斥的,
    top_to_bottom和bottom_to_top是互斥的。
    如果不指定 direction字段,
    默認值為left_to_right | top_to_bottom;
    即從上往下,從左往右。
    animation: gridview內部元素所使用的動畫。

布局增加/移除動畫
  1. android:animateLayoutChanges="true"
    只要給布局添加該屬性,它內部的控件在添加和刪除時,是會帶有默認動畫
  2. LayoutTransaction ,允許我們自定義動畫效果
    LayoutTransaction transitioner = new LayoutTransition();
    ObjectAnimator animOut = ObjectAnimator.ofFloat(null, "rotation", 0f, 90f, 0f);
    //設置動畫
    //第一個參數int transitionType:表示當前應用動畫的對象范圍,取值有:
    //APPEARING —— 添加元素的動畫
    //DISAPPEARING —— 移除元素的動畫
    //CHANGE_APPEARING —— 添加元素時,其它元素的動畫(該動畫必須通過PropertyValuesHolder創建)
    //CHANGE_DISAPPEARING —— 移除元素時,其它元素的動畫(該動畫必須通過PropertyValuesHolder創建)
    //第二個參數Animator animator:表示當前所選范圍的控件所使用的動畫。
    transitioner.setAnimator(LayoutTransition.DISAPPEARING, animOut);
    //將LayoutTransaction設置進ViewGroup
    linearLayout.setLayoutTransition(mTransitioner);
    因為LayoutTransaction 使用的機會不多,且實際應用相對麻煩,所以不再詳細說明
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,428評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,024評論 3 413
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,285評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,548評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,328評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,878評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,971評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,098評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,616評論 1 331
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,554評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,725評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,243評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 43,971評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,361評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,613評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,339評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,695評論 2 370

推薦閱讀更多精彩內容