Android_之動畫2

現在隆重介紹Android動畫中無所不能的屬性動畫登場,先看看官方文檔對屬性動畫的介紹:

The property animation system is a robust framework that allows you to animate almost anything. You can define an animation to change any object property over time, regardless of whether it draws to the screen or not. A property animation changes a property's (a field in an object) value over a specified length of time. To animate something, you specify the object property that you want to animate, such as an object's position on the screen, how long you want to animate it for, and what values you want to animate between.

是不是很牛逼。。。確實很牛逼,翻譯過來的意思大概是(英語比較挫,翻譯不對的大家指正):屬性動畫是一個能爲所有事情添加動畫的非常健壯的框架,可以通過控件的任意屬性,實現控件對話(算了,翻譯不下去了),下面開始搞起。首先說明一點,動畫原理什麼滴,這裏就不多講了,網上有很多,大家可以去官網開說明:http://developer.android.com/guide/topics/graphics/prop-animation.html#value-animator,我就只講講如何使用,使用最重要嘛。如果想看中文的話,請看AngelDevi的一篇文章,http://www.cnblogs.com/angeldevil/archive/2011/12/02/2271096.html,根據這篇文章你應該瞭解屬性動畫是如何工作的。

(1)寫一個屬性動畫需要準備哪些工作?

Android屬性動畫開始需要準備 TimeInterpolatorTypeEvaluatorTimeInterpolator是用來定義插值器的,下表列出Android的幾種插值器,可以根據自己的需求,選擇不同的插值器。更加詳盡的闡述請見http://my.oschina.net/banxi/blog/135633


AccelerateInterpolator一開始很慢,然後逐漸加速
DecelerateInterpolator 一開始很快,然後逐漸減速
AccelerateDecelerateInterpolator 變化率開始慢,然後從中間開始加速,然後再減速
LinearInterpolator 線性插值器,勻速
BounceInterpolator 彈跳插值器,類似與小球落到地面彈跳得效果,自行腦補
AnticipateInterpolator 回盪鞦韆插值器
AnticipateOverShotInterpolator 它開始向上推,然後向下蕩,蕩過最低線。然後再回到最低線
CycleInterpolator 正弦週期變化插值器
OverShotInterpolator 

TypeEvaluatorValueAnimator根據動畫已進行的時間跟動畫總時間(duration)的比計算出一個時間因子(0~1),然後根據TimeInterpolator計算出另一個因子,最後TypeAnimator通過這個因子計算出屬性值,如上例中10ms時:

首先計算出時間因子,即經過的時間百分比:t=10ms/40ms=0.25經插值計算(inteplator)後的插值因子:大約爲0.15,上述例子中用了AccelerateDecelerateInterpolator,計算公式爲(input即爲時間因子):

(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;

最後根據TypeEvaluator計算出在10ms時的屬性值:0.15*(40-0)=6pixel。上例中TypeEvaluator爲FloatEvaluator,計算方法爲 :

public Float evaluate(float fraction, Number startValue, Number endValue) {    float startFloat = startValue.floatValue();    
     return startFloat + fraction * (endValue.floatValue() - startFloat);
}

參數分別爲上一步的插值因子,開始值與結束值。大家可能對fraction理解有偏差,按照字面意思fraction是片段的意思,這個片段並不是時間片段,而是相當於任務完成的百分比。

(2)開始做一個屬性動畫

代碼1:

 private void performAnimate(final View target, final int start, final int end) {
 //定義一個屬性動畫,並定義初始值和結束值
 ValueAnimator valueAnimator = ValueAnimator.ofInt(1, 100);
 //爲屬性動畫添加監聽事件
    valueAnimator.addUpdateListener(new AnimatorUpdateListener() {
 
        //持有一個IntEvaluator對象,方便下面估值的時候使用
        private IntEvaluator mEvaluator = new IntEvaluator();
 
        @Override
        public void onAnimationUpdate(ValueAnimator animator) {
            //獲得當前動畫的進度值,整型,1-100之間
            int currentValue = (Integer)animator.getAnimatedValue();
            Log.d(TAG, current value:  + currentValue);
 
            //計算當前進度佔整個動畫過程的比例,浮點型,0-1之間
            float fraction = currentValue / 100f;
 
            //這裏我偷懶了,不過有現成的幹嗎不用呢
            //直接調用整型估值器通過比例計算出寬度,然後再設給Button
            target.getLayoutParams().width = mEvaluator.evaluate(fraction, start, end);
            target.requestLayout();
        }
    });
 
    valueAnimator.setDuration(5000).start();
    }
    //按鈕點擊時,觸發動畫
    @Override
public void onClick(View v) {
    if (v == mButton) {
        performAnimate(mButton, mButton.getWidth(), 500);
    }
}

 上述代碼當中並沒有使用插值器,因爲他自己實現了一個插值器功能,原因在與插值器的作用是計算任務完成量,但是這段代碼中是自己計算的,是線性插值。

代碼2:

ValueAnimator scan_anim = ValueAnimator.ofInt(30, 2*RADIUS-30);
scan_anim.setInterpolator(new  LinearInterpolator());
scan_anim.setRepeatCount ( Integer.MAX_VALUE );
scan_anim.setRepeatMode (ValueAnimator.REVERSE);
scan_anim.addUpdateListener(new AnimatorUpdateListener() {
private IntEvaluator mEvaluator = new IntEvaluator();
@Override
public void onAnimationUpdate(ValueAnimator valueAnimator) {
// TODO Auto-generated method stub
//計算結果
scan_y = (Integer) valueAnimator.getAnimatedValue();
invalidate();
}
});
scan_anim.setDuration(800);
scan_anim.start();

屬性動畫流程圖如下:

wKiom1OcKTuA3zaEAAGhk1k5nzs915.jpg






















發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章