Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 動畫(anim)詳解

Android 動畫(anim)詳解

編輯:關於Android編程

Android 動畫(anim)詳解

就我所知,簡單闡述一下: Android的animation由四種類型組成:alpha(透明度)、scale(縮放)、translate(位移)、rotate(旋轉)

XML配置文件中

android:alpha
漸變透明度動畫效果
android:scale
漸變縮放動畫效果
android:translate
畫面轉換位置移動動畫效果
android:rotate
畫面轉移旋轉動畫效果


Java Code代碼中
AlphaAnimation
漸變透明度動畫效果
ScaleAnimation
漸變縮放動畫效果
TranslateAnimation
畫面轉換位置移動動畫效果
RotateAnimation
畫面轉移旋轉動畫效果

Alpha


 

AlphaAnimation(float fromAlpha, float toAlpha) 
//第一個參數fromAlpha為 動畫開始時候透明度
//第二個參數toAlpha為 動畫結束時候透明度

Scale


   

ScaleAnimation(float fromX, float toX, float fromY, float toY,
           int pivotXType, float pivotXValue, int pivotYType, float pivotYValue) 
//第一個參數fromX為動畫起始時 X坐標上的伸縮尺寸    
//第二個參數toX為動畫結束時 X坐標上的伸縮尺寸     
//第三個參數fromY為動畫起始時Y坐標上的伸縮尺寸    
//第四個參數toY為動畫結束時Y坐標上的伸縮尺寸  
/*說明:
                    以上四種屬性值    
                    0.0表示收縮到沒有 
                    1.0表示正常無伸縮     
                    值小於1.0表示收縮  
                    值大於1.0表示放大
*/
//第五個參數pivotXType為動畫在X軸相對於物件位置類型  
//第六個參數pivotXValue為動畫相對於物件的X坐標的開始位置
//第七個參數pivotXType為動畫在Y軸相對於物件位置類型   
//第八個參數pivotYValue為動畫相對於物件的Y坐標的開始位置
myAnimation_Scale = new ScaleAnimation(0.0f, 1.4f, 0.0f, 1.4f,
             Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);

Translate





TranslateAnimation(float fromXDelta, float toXDelta,
                       float fromYDelta, float toYDelta) 
//第一個參數fromXDelta為動畫起始時 X坐標上的位置    
//第二個參數toXDelta為動畫結束時 X坐標上的位置      
//第三個參數fromYDelta為動畫起始時Y坐標上的位置     
//第四個參數toYDelta為動畫結束時Y坐標上的位置
myAnimation_Translate = new TranslateAnimation(10f, 100f, 10f, 100f);

Rorate


  


RotateAnimation(float fromDegrees, float toDegrees, 
            int pivotXType, float pivotXValue, int pivotYType, float pivotYValue)
//第一個參數fromDegrees為動畫起始時的旋轉角度    
//第二個參數toDegrees為動畫旋轉到的角度   
//第三個參數pivotXType為動畫在X軸相對於物件位置類型  
//第四個參數pivotXValue為動畫相對於物件的X坐標的開始位置
//第五個參數pivotXType為動畫在Y軸相對於物件位置類型   
//第六個參數pivotYValue為動畫相對於物件的Y坐標的開始位置
myAnimation_Rotate = new RotateAnimation(0.0f, +350.0f,
               Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF, 0.5f);

Android有三種動畫模式 :Tween Animation(補間動畫)、Frame Animation(逐幀動畫)、Property Animation(屬性動畫)

1. View Animation(Tween Animation)

View Animation(Tween Animation):補間動畫,給出兩個關鍵幀,通過一些算法將給定屬性值在給定的時間內在兩個關鍵幀間漸變。

View animation只能應用於View對象,而且只支持一部分屬性,如支持縮放旋轉而不支持背景顏色的改變。

而且對於View animation,它只是改變了View對象繪制的位置,而沒有改變View對象本身,比如,你有一個Button,坐標(100,100),Width:200,Height:50,而你有一個動畫使其變為Width:100,Height:100,你會發現動畫過程中觸發按鈕點擊的區域仍是(100,100)-(300,150)。

View Animation就是一系列View形狀的變換,如大小的縮放,透明度的改變,位置的改變,動畫的定義既可以用代碼定義也可以用XML定義,當然,建議用XML定義。

可以給一個View同時設置多個動畫,比如從透明至不透明的淡入效果,與從小到大的放大效果,這些動畫可以同時進行,也可以在一個完成之後開始另一個。

用XML定義的動畫放在/res/anim/文件夾內,XML文件的根元素可以為,,,,interpolator元素或(表示以上幾個動畫的集合,set可以嵌套)。默認情況下,所有動畫是同時進行的,可以通過startOffset屬性設置各個動畫的開始偏移(開始時間)來達到動畫順序播放的效果。

可以通過設置interpolator屬性改變動畫漸變的方式,如AccelerateInterpolator,開始時慢,然後逐漸加快。默認為AccelerateDecelerateInterpolator。

定義好動畫的XML文件後,可以通過類似下面的代碼對指定View應用動畫。

ImageView spaceshipImage = (ImageView)findViewById(R.id.spaceshipImage);
Animation hyperspaceJumpAnimation=AnimationUtils.loadAnimation(this, R.anim.hyperspace_jump;
spaceshipImage.startAnimation(hyperspaceJumpAnimation);

2. Drawable Animation(Frame Animation)

Drawable Animation(Frame Animation):幀動畫,就像GIF圖片,通過一系列Drawable依次顯示來模擬動畫的效果。在XML中的定義方式如下:

    
    
    

protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        imageView = (ImageView) findViewById(R.id.imageView1);
        imageView.setBackgroundResource(R.drawable.drawable_anim);
        anim = (AnimationDrawable) imageView.getBackground();
    }

    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            anim.stop();
            anim.start();
            return true;
        }
        return super.onTouchEvent(event);
    }
注意:
  • 要在代碼中調用Imageview的setBackgroundResource方法,如果直接在XML布局文件中設置其src屬性當觸發動畫時會FC。
  • 在動畫start()之前要先stop(),不然在第一次動畫之後會停在最後一幀,這樣動畫就只會觸發一次。
  • 最後一點是SDK中提到的,不要在onCreate中調用start,因為AnimationDrawable還沒有完全跟Window相關聯,如果想要界面顯示時就開始動畫的話,可以在onWindowFoucsChanged()中調用start()。

    3. Property Animation

    屬性動畫,這個是在Android 3.0中才引進的,它更改的是對象的實際屬性,在View Animation(Tween Animation)中,其改變的是View的繪制效果,真正的View的屬性保持不變,比如無論你在對話中如何縮放Button的大小,Button的有效點擊區域還是沒有應用動畫時的區域,其位置與大小都不變。而在Property Animation中,改變的是對象的實際屬性,如Button的縮放,Button的位置與大小屬性值都改變了。而且Property Animation不止可以應用於View,還可以應用於任何對象。Property Animation只是表示一個值在一段時間內的改變,當值改變時要做什麼事情完全是你自己決定的。

    在Property Animation中,可以對動畫應用以下屬性:

    • Duration:動畫的持續時間
    • TimeInterpolation:屬性值的計算方式,如先快後慢
    • TypeEvaluator:根據屬性的開始、結束值與TimeInterpolation計算出的因子計算出當前時間的屬性值
    • Repeat Count and behavoir:重復次數與方式,如播放3次、5次、無限循環,可以此動畫一直重復,或播放完時再反向播放
    • Animation sets:動畫集合,即可以同時對一個對象應用幾個動畫,這些動畫可以同時播放也可以對不同動畫設置不同開始偏移
    • Frame refreash delay:多少時間刷新一次,即每隔多少時間計算一次屬性值,默認為10ms,最終刷新時間還受系統進程調度與硬件的影響


      Interpolator


      首先要了解為什麼需要插值器,因為在補間動畫中,我們一般只定義關鍵幀(首幀或尾幀),然後由系統自動生成中間幀,生成中間幀的這個過程可以成為“插值”。插值器定義了動畫變化的速率,提供不同的函數定義變化值相對於時間的變化規則,可以定義各種各樣的非線性變化函數,比如加速、減速等。下面是幾種常見的插值器:

      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 快速到達終點並超出一小步最後回到終點

      如果只簡單地引用這些插值器還不能滿足需要的話,我們要考慮一下個性化插值器。我們可以創建一個插值器資源修改插值器的屬性,比如修改AnticipateInterpolator的加速速率,調整CycleInterpolator的循環次數等。為了完成這種需求,我們需要創建XML資源文件,然後將其放於/res/anim下,然後再動畫元素中引用即可。我們先來看一下幾種常見的插值器可調整的屬性:

       無
       android:factor 浮點值,加速速率,默認為1
       android:tension 浮點值,起始點後退的張力、拉力數,默認為2
       android:tension 同上 android:extraTension 浮點值,拉力的倍數,默認為1.5(2  * 1.5)
       android:cycles 整數值,循環的個數,默認為1
       android:factor 浮點值,減速的速率,默認為1
       浮點值,超出終點後的張力、拉力,默認為2


      下面我們就拿最後一個插值器來舉例:

      
      

      上面的代碼中,我們把張力改為7.0,然後將此文件命名為my_overshoot_interpolator.xml,放置於/res/anim下,我們就可以引用到自定義的插值器了:


      AccelerateDecelerateInterpolator

      /**
       * An interpolator where the rate of change starts and ends slowly but
       * accelerates through the middle.
       * 
       */
      public class AccelerateDecelerateInterpolator implements Interpolator {
          public AccelerateDecelerateInterpolator() {
          }
          
          @SuppressWarnings({"UnusedDeclaration"})
          public AccelerateDecelerateInterpolator(Context context, AttributeSet attrs) {
          }
          
          public float getInterpolation(float input) {
              return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
          }
      }


      \

      <喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4KPGgyPgpBY2NlbGVyYXRlSW50ZXJwb2xhdG9yPC9oMj4KPHByZSBjbGFzcz0="brush:java;">/** * An interpolator where the rate of change starts out slowly and * and then accelerates. * */ public class AccelerateInterpolator implements Interpolator { private final float mFactor; private final double mDoubleFactor; public AccelerateInterpolator() { mFactor = 1.0f; mDoubleFactor = 2.0; } /** * Constructor * * @param factor Degree to which the animation should be eased. Seting * factor to 1.0f produces a y=x^2 parabola. Increasing factor above * 1.0f exaggerates the ease-in effect (i.e., it starts even * slower and ends evens faster) */ public AccelerateInterpolator(float factor) { mFactor = factor; mDoubleFactor = 2 * mFactor; } public AccelerateInterpolator(Context context, AttributeSet attrs) { TypedArray a = context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.AccelerateInterpolator); mFactor = a.getFloat(com.android.internal.R.styleable.AccelerateInterpolator_factor, 1.0f); mDoubleFactor = 2 * mFactor; a.recycle(); } public float getInterpolation(float input) { if (mFactor == 1.0f) { return input * input; } else { return (float)Math.pow(input, mDoubleFactor); } } }

      \

      AnticipateInterpolator

      /**
       * An interpolator where the change starts backward then flings forward.
       */
      public class AnticipateInterpolator implements Interpolator {
          private final float mTension;
      
          public AnticipateInterpolator() {
              mTension = 2.0f;
          }
      
          /**
           * @param tension Amount of anticipation. When tension equals 0.0f, there is
           *                no anticipation and the interpolator becomes a simple
           *                acceleration interpolator.
           */
          public AnticipateInterpolator(float tension) {
              mTension = tension;
          }
      
          public AnticipateInterpolator(Context context, AttributeSet attrs) {
              TypedArray a = context.obtainStyledAttributes(attrs,
                      com.android.internal.R.styleable.AnticipateInterpolator);
      
              mTension =
                      a.getFloat(com.android.internal.R.styleable.AnticipateInterpolator_tension, 2.0f);
      
              a.recycle();
          }
      
          public float getInterpolation(float t) {
              // a(t) = t * t * ((tension + 1) * t - tension)
              return t * t * ((mTension + 1) * t - mTension);
          }
      }


      \

      AnticipateOvershootInterpolator

      /**
       * An interpolator where the change starts backward then flings forward and overshoots
       * the target value and finally goes back to the final value.
       */
      public class AnticipateOvershootInterpolator implements Interpolator {
          private final float mTension;
      
          public AnticipateOvershootInterpolator() {
              mTension = 2.0f * 1.5f;
          }
      
          /**
           * @param tension Amount of anticipation/overshoot. When tension equals 0.0f,
           *                there is no anticipation/overshoot and the interpolator becomes
           *                a simple acceleration/deceleration interpolator.
           */
          public AnticipateOvershootInterpolator(float tension) {
              mTension = tension * 1.5f;
          }
      
          /**
           * @param tension Amount of anticipation/overshoot. When tension equals 0.0f,
           *                there is no anticipation/overshoot and the interpolator becomes
           *                a simple acceleration/deceleration interpolator.
           * @param extraTension Amount by which to multiply the tension. For instance,
           *                     to get the same overshoot as an OvershootInterpolator with
           *                     a tension of 2.0f, you would use an extraTension of 1.5f.
           */
          public AnticipateOvershootInterpolator(float tension, float extraTension) {
              mTension = tension * extraTension;
          }
      
          public AnticipateOvershootInterpolator(Context context, AttributeSet attrs) {
              TypedArray a = context.obtainStyledAttributes(attrs, AnticipateOvershootInterpolator);
      
              mTension = a.getFloat(AnticipateOvershootInterpolator_tension, 2.0f) *
                      a.getFloat(AnticipateOvershootInterpolator_extraTension, 1.5f);
      
              a.recycle();
          }
      
          private static float a(float t, float s) {
              return t * t * ((s + 1) * t - s);
          }
      
          private static float o(float t, float s) {
              return t * t * ((s + 1) * t + s);
          }
      
          public float getInterpolation(float t) {
              // a(t, s) = t * t * ((s + 1) * t - s)
              // o(t, s) = t * t * ((s + 1) * t + s)
              // f(t) = 0.5 * a(t * 2, tension * extraTension), when t < 0.5
              // f(t) = 0.5 * (o(t * 2 - 2, tension * extraTension) + 2), when t <= 1.0
              if (t < 0.5f) return 0.5f * a(t * 2.0f, mTension);
              else return 0.5f * (o(t * 2.0f - 2.0f, mTension) + 2.0f);
          }
      }


      \

      BounceInterpolator

      /**
       * An interpolator where the change bounces at the end.
       */
      public class BounceInterpolator implements Interpolator {
          public BounceInterpolator() {
          }
      
          @SuppressWarnings({"UnusedDeclaration"})
          public BounceInterpolator(Context context, AttributeSet attrs) {
          }
      
          private static float bounce(float t) {
              return t * t * 8.0f;
          }
      
          public float getInterpolation(float t) {
              // _b(t) = t * t * 8
              // bs(t) = _b(t) for t < 0.3535
              // bs(t) = _b(t - 0.54719) + 0.7 for t < 0.7408
              // bs(t) = _b(t - 0.8526) + 0.9 for t < 0.9644
              // bs(t) = _b(t - 1.0435) + 0.95 for t <= 1.0
              // b(t) = bs(t * 1.1226)
              t *= 1.1226f;
              if (t < 0.3535f) return bounce(t);
              else if (t < 0.7408f) return bounce(t - 0.54719f) + 0.7f;
              else if (t < 0.9644f) return bounce(t - 0.8526f) + 0.9f;
              else return bounce(t - 1.0435f) + 0.95f;
          }
      }


      \

      CycleInterpolator

      /**
       * Repeats the animation for a specified number of cycles. The
       * rate of change follows a sinusoidal pattern.
       *
       */
      public class CycleInterpolator implements Interpolator {
          public CycleInterpolator(float cycles) {
              mCycles = cycles;
          }
          
          public CycleInterpolator(Context context, AttributeSet attrs) {
              TypedArray a =
                  context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.CycleInterpolator);
              
              mCycles = a.getFloat(com.android.internal.R.styleable.CycleInterpolator_cycles, 1.0f);
              
              a.recycle();
          }
          
          public float getInterpolation(float input) {
              return (float)(Math.sin(2 * mCycles * Math.PI * input));
          }
          
          private float mCycles;
      }


        參數為2時的曲線:

      \

      DecelerateInterpolator


      /**
       * An interpolator where the rate of change starts out quickly and 
       * and then decelerates.
       *
       */
      public class DecelerateInterpolator implements Interpolator {
          public DecelerateInterpolator() {
          }
      
          /**
           * Constructor
           * 
           * @param factor Degree to which the animation should be eased. Setting factor to 1.0f produces
           *        an upside-down y=x^2 parabola. Increasing factor above 1.0f makes exaggerates the
           *        ease-out effect (i.e., it starts even faster and ends evens slower)
           */
          public DecelerateInterpolator(float factor) {
              mFactor = factor;
          }
          
          public DecelerateInterpolator(Context context, AttributeSet attrs) {
              TypedArray a =
                  context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.DecelerateInterpolator);
              
              mFactor = a.getFloat(com.android.internal.R.styleable.DecelerateInterpolator_factor, 1.0f);
              
              a.recycle();
          }
          
          public float getInterpolation(float input) {
              float result;
              if (mFactor == 1.0f) {
                  result = (float)(1.0f - (1.0f - input) * (1.0f - input));
              } else {
                  result = (float)(1.0f - Math.pow((1.0f - input), 2 * mFactor));
              }
              return result;
          }
          
          private float mFactor = 1.0f;
      }

      \

      LinearInterpolator

      /**
       * An interpolator where the rate of change is constant
       *
       */
      public class LinearInterpolator implements Interpolator {
      
          public LinearInterpolator() {
          }
          
          public LinearInterpolator(Context context, AttributeSet attrs) {
          }
          
          public float getInterpolation(float input) {
              return input;
          }
      }


      \

      OvershootInterpolator

      /**
       * An interpolator where the change flings forward and overshoots the last value
       * then comes back.
       */
      public class OvershootInterpolator implements Interpolator {
          private final float mTension;
      
          public OvershootInterpolator() {
              mTension = 2.0f;
          }
      
          /**
           * @param tension Amount of overshoot. When tension equals 0.0f, there is
           *                no overshoot and the interpolator becomes a simple
           *                deceleration interpolator.
           */
          public OvershootInterpolator(float tension) {
              mTension = tension;
          }
      
          public OvershootInterpolator(Context context, AttributeSet attrs) {
              TypedArray a = context.obtainStyledAttributes(attrs,
                      com.android.internal.R.styleable.OvershootInterpolator);
      
              mTension =
                      a.getFloat(com.android.internal.R.styleable.OvershootInterpolator_tension, 2.0f);
      
              a.recycle();
          }
      
          public float getInterpolation(float t) {
              // _o(t) = t * t * ((tension + 1) * t + tension)
              // o(t) = _o(t - 1) + 1
              t -= 1.0f;
              return t * t * ((mTension + 1) * t + mTension) + 1.0f;
          }
      }




    • 要在代碼中調用Imageview的setBackgroundResource方法,如果直接在XML布局文件中設置其src屬性當觸發動畫時會FC。
    • 在動畫start()之前要先stop(),不然在第一次動畫之後會停在最後一幀,這樣動畫就只會觸發一次。
    • 最後一點是SDK中提到的,不要在onCreate中調用start,因為AnimationDrawable還沒有完全跟Window相關聯,如果想要界面顯示時就開始動畫的話,可以在onWindowFoucsChanged()中調用start()。
    1. 上一頁:
    2. 下一頁:
    熱門文章
    閱讀排行版
    Copyright © Android教程網 All Rights Reserved