animation of android (3)

视图动画,只有view可以使用。

在android3.0以后,属性动画。

ValueAnimation 可以记录属性变化的过程,所以他的对象是任何object。

所以ValueAnimation 的真正目的就是对object的某个值做一系列根据setInterpolator的值变化函数。

而ValueAnimation 有AnimatorUpdateListener的回调,以每个10ms的间隔,反馈随着时间的变化值。

具体代码如下:

package com.joyfulmath.animatatorsamples;

import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Paint.FontMetrics;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.animation.BounceInterpolator;

public class ValueAnimationView extends View {

    private static final String TAG = "ValueAnimationView";
    private Context mContext = null;
    private Paint mPaint = null;
    private float mX = 0;
    float topY = 0;  
    private ValueAnimator mValueAnimator = null;
    public ValueAnimationView(Context context) {
        this(context, null);
    }

    public ValueAnimationView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ValueAnimationView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        Log.d(TAG, "ValueAnimationView");
        mContext = context;
    }
    
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        Log.d(TAG, "onDraw:mX\t"+mX);
        canvas.drawColor(0xffffff00);
        canvas.save();
        canvas.translate(0, 0);
        canvas.drawText(TAG, mX, mX-topY, mPaint);
        canvas.restore();
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        Log.d(TAG, "onAttachedToWindow");
        mPaint = new Paint();
        mPaint.setTextSize(18);
        mPaint.setTextAlign(Align.LEFT);
        mPaint.setColor(0xffff0000);
        mPaint.setAntiAlias(true);
        FontMetrics fontMetrics = mPaint.getFontMetrics();
        topY = fontMetrics.top;  
        float ascentY = fontMetrics.ascent;  
        float descentY = fontMetrics.descent;  
        float bottomY = fontMetrics.bottom; 
        Log.d(TAG, "onAttachedToWindow fontMetrics  topY:" + topY
                + "\t ascentY:" + ascentY + "\t descentY:" + descentY
                + "\t bottomY:" + bottomY);
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
    }
    
    public void createAnimator()
    {
        if(mValueAnimator == null)
        {
            mValueAnimator = ValueAnimator.ofFloat(0.0f, 50.0f);
            mValueAnimator.setDuration(1000);
            mValueAnimator.setInterpolator(new BounceInterpolator());
            mValueAnimator.addUpdateListener(new AnimatorUpdateListener() {
                
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    mX = (Float) animation.getAnimatedValue();
                    invalidate();
                }
            });
        }

    }
    
    public void startValueAmimator()
    {
        Log.d(TAG, "startValueAmimator");
        createAnimator();
        mValueAnimator.start();
    }
}

上面的代码,是自定义view,实现动画的一个基础。

关键就是每次OnDraw的时候,获取objcet动画的属性。

而触发条件就是:

            mValueAnimator.addUpdateListener(new AnimatorUpdateListener() {
                
                @Override
                public void onAnimationUpdate(ValueAnimator animation) {
                    mX = (Float) animation.getAnimatedValue();
                    invalidate();//触发onDraw
                }
            });
        }

所以valueObjcet的关键就是会在动画过程中改变object的属性,以此来决定如何通过这个变化来实现动画。

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。