码迷,mamicode.com
首页 > 其他好文 > 详细

Animation动画的解析

时间:2015-04-27 09:49:42      阅读:145      评论:0      收藏:0      [点我收藏+]

标签:animation   效果   动画   

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

Animation的动画原理

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

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 moon.zhong on 2015/4/23.
 */
public class ScaleAnimation extends Animation {
    private View mTarget ;
    private int mOriginWidth ;
    private int mTargetWidth;
    private ViewGroup.LayoutParams mParams ;

    public ScaleAnimation(int mTargetWidth, View target) {
        this.mTarget = target;
        this.mOriginWidth = mTarget.getMeasuredWidth();
        this.mTargetWidth = mTargetWidth;
        if (mOriginWidth == 0 ){
            mTarget.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
                @Override
                public boolean onPreDraw() {
                    mTarget.getViewTreeObserver().removeOnPreDrawListener(this);
                    mOriginWidth = mTarget.getMeasuredWidth() ;
                    return false;
                }
            });
        }
        mParams = target.getLayoutParams() ;
    }

    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        /*interpolatedTime
        * 变化范围
        * 0~1
        * */
        mParams.width = (int) (mOriginWidth + (mTargetWidth - mOriginWidth)*interpolatedTime) ;
        mTarget.setLayoutParams(mParams);
    }
}

使用代码:


    public void startAnimation(View view){
        final float density =  getResources().getDisplayMetrics().density;
        int width = (int) (300 * density);
        ScaleAnimation animation = new ScaleAnimation(width,mTargetView) ;
        animation.setDuration(2000);
        mTargetView.startAnimation(animation);
    }

效果图:
技术分享

再来一张拉伸的效果图对比:
技术分享

总结:

总体来说还是非常简单的,这里我只是定义了一个简单的动画,同理定义一个复杂一点的动画也是同样的操作,只是applyTransformation里面的代码写的多一点而已。
本篇blog的知识点主要有:
1、Animation的运用场景,作用于View中;
2、系统Animation的使用

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

这种形式,当然还有读取xml的形式,这里没有提及到
3、自定义Animation
重写applyTransformation 方法

Demo源码
http://download.csdn.net/detail/jxxfzgy/8634819

Animation动画的解析

标签:animation   效果   动画   

原文地址:http://blog.csdn.net/jxxfzgy/article/details/45305629

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!