Animation动画的解析与自定义Animation

来源:互联网 发布:兼职开淘宝店怎样 编辑:程序博客网 时间:2024/06/05 13:35

Animation在View的包下,我们通过Animation的原理也可知道,Animation离开了View就没有效果,为什么这么说呢?

Animation的动画原理

我们先看一个简单的Animation动画,AlphaAnimation:

/** * An animation that controls the alpha level of an object. * Useful for fading things in and out. This animation ends up * changing the alpha property of a {@link Transformation} * */public class AlphaAnimation extends Animation {    private float mFromAlpha;    private float mToAlpha;    /**     * Constructor used when an AlphaAnimation is loaded from a resource.      *      * @param context Application context to use     * @param attrs Attribute set from which to read values     */    public AlphaAnimation(Context context, AttributeSet attrs) {        super(context, attrs);        TypedArray a =            context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.AlphaAnimation);        mFromAlpha = a.getFloat(com.android.internal.R.styleable.AlphaAnimation_fromAlpha, 1.0f);        mToAlpha = a.getFloat(com.android.internal.R.styleable.AlphaAnimation_toAlpha, 1.0f);        a.recycle();    }    /**     * Constructor to use when building an AlphaAnimation from code     *      * @param fromAlpha Starting alpha value for the animation, where 1.0 means     *        fully opaque and 0.0 means fully transparent.     * @param toAlpha Ending alpha value for the animation.     */    public AlphaAnimation(float fromAlpha, float toAlpha) {        mFromAlpha = fromAlpha;        mToAlpha = toAlpha;    }    /**     * Changes the alpha property of the supplied {@link Transformation}     */    @Override    protected void applyTransformation(float interpolatedTime, Transformation t) {        final float alpha = mFromAlpha;        t.setAlpha(alpha + ((mToAlpha - alpha) * interpolatedTime));    }    @Override    public boolean willChangeTransformationMatrix() {        return false;    }    @Override    public boolean willChangeBounds() {        return false;    }    /**     * @hide     */    @Override    public boolean hasAlpha() {        return true;    }}

代码非常简单,其核心代码就在

@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final float alpha = mFromAlpha;
t.setAlpha(alpha + ((mToAlpha - alpha) * interpolatedTime));
}
通过interpolatedTime来不断给变alpha的值,我们就可以看到一个View实现透明度变化的动画效果!那么问题来了,谁在调用applyTransformation方法呢?跟进代码看到

public boolean getTransformation(long currentTime, Transformation outTransformation){
}
中对applyTransformation做了调用,不用想了,getTransformation肯定是在View的startAnimation触发的!
是不是呢?

public void startAnimation(Animation animation) {
animation.setStartTime(Animation.START_ON_FIRST_FRAME);
setAnimation(animation);
invalidateParentCaches();
invalidate(true);
}
这里重新绘制了View,所以View的boolean draw(Canvas canvas, ViewGroup parent, long drawingTime)方法会被执行,为什么是draw而不是onDraw,我们看着么一句注解

/** * This method is called by ViewGroup.drawChild() to have each child view draw itself. * This draw() method is an implementation detail and is not intended to be overridden or * to be called from anywhere else other than ViewGroup.drawChild(). */

而在draw()方法中有

final Animation a = getAnimation();
if (a != null) {
more = drawAnimation(parent, drawingTime, a, scalingRequired);
concatMatrix = a.willChangeTransformationMatrix();
if (concatMatrix) {
mPrivateFlags3 |= PFLAG3_VIEW_IS_ANIMATING_TRANSFORM;
}
transformToApply = parent.getChildTransformation();
}
所以Animation得getTransformation的到执行,这就是Animation的实现原理。

但这好像对于我们来说意义不大,确实,因为我们不是Animation的缔造者,我们你只需要知道如何使用即可,就当前面热热身了!

Animation的使用

Animation的使用非常简单,Android中已经为我们定义好了四种Animation动画效果AlphaAnimation、RotateAnimation、ScaleAnimation、TranslateAnimation
以AlphaAnimation为例快速的说明一下其使用方法:

AlphaAnimation animation = new AlphaAnimation(1,0;animation.setDuration(2000) ;animation.setRepeat(2) ;view.startAnimation(animation);

ok,一个View的动画就实现了,其他三个动画效果也是类似的,非常简单!这里不重复了,我们重点来看一下如何自己定义一个Animation效果,还是通过一个案例来说明。

实现一个按钮放大的动画效果,这里放大不能出现拉伸,如果可以拉伸那就没意义了,因为系统已经为我们定义好了一个,ScaleAnimation就可以实现;

第一步 、继承Animation,
第二步 、重写applyTransformation方法
第三步、没了!

所以代码如下:

/** * Created by zhuxiaocheng on 2016/6/15. */public class ParamsScaleAnimation extends Animation {    private View mTargetView;    private int mOriginWidth;    private int mTargetWidth;    private ViewGroup.LayoutParams mLayoutParams;    public ParamsScaleAnimation(final int mTargetWidth, final View mTargetView){        this.mTargetView = mTargetView;        this.mOriginWidth = mTargetView.getMeasuredWidth();        this.mTargetWidth = mTargetWidth;        if (mOriginWidth==0){            mTargetView.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {                @Override                public boolean onPreDraw() {                    mTargetView.getViewTreeObserver().removeOnPreDrawListener(this);                    mOriginWidth = mTargetView.getMeasuredWidth();                    return false;                }            });        }        mLayoutParams = mTargetView.getLayoutParams();    }    @Override    protected void applyTransformation(float interpolatedTime, Transformation t) {        /**         * interpolatedTime 变化范围 0~1         */        mLayoutParams.width = (int)(mOriginWidth + (mTargetWidth-mOriginWidth)*interpolatedTime);        mTargetView.setLayoutParams(mLayoutParams);    }}

使用代码:

  private void startParamsAnimation(View view){        float density = getResources().getDisplayMetrics().density;        int width = (int) (300*density);        ParamsScaleAnimation paramsScaleAnimation = new ParamsScaleAnimation(width,view);        paramsScaleAnimation.setDuration(2000);        view.startAnimation(paramsScaleAnimation);    }

这里写图片描述

最后附上代码:最后附上代码:

0 0
原创粉丝点击