自定义视图动画类Animator和自定义插值器Interpolator以及他们之间的关系


1、自定义视图动画,这个比较简单,直接上代码:

public class MyAnimation extends Animation {
    private int mCenterWidth,mCenterHeight;

    public MyAnimation(int mCenterWidth,int mCenterHeight){
        this.mCenterWidth = mCenterWidth;
        this.mCenterHeight = mCenterHeight;
    }

//自定義視圖動畫的主要邏輯
    @Override
    protected void applyTransformation(float interpolatedTime, Transformation t) {
        Log.e("time",interpolatedTime+"");
        final Matrix matrix = t.getMatrix();
        matrix.preScale(1,1-interpolatedTime,mCenterWidth,mCenterHeight);
    }
}
2、自定义插值器,这个也直接上代码:
public class MyInterpolator implements android.view.animation.Interpolator {


    //自定義插值器的主要邏輯
    @Override
    public float getInterpolation(float input) {
        return input*2;
    }
}

3、主要讲解他们之间是如何工作的:
这是Animation基类中的getTranslation方法:
public boolean getTransformation(long currentTime, Transformation outTransformation) {
    if (mStartTime == -1) {
        mStartTime = currentTime;
    }

    final long startOffset = getStartOffset();
    final long duration = mDuration;
    float normalizedTime;
    if (duration != 0) {
        normalizedTime = ((float) (currentTime - (mStartTime + startOffset))) /
                (float) duration;
    } else {
        // time is a step-change with a zero duration
        normalizedTime = currentTime < mStartTime ? 0.0f : 1.0f;
    }

   //省略一部分代码
        final float interpolatedTime = mInterpolator.getInterpolation(normalizedTime);
        applyTransformation(interpolatedTime, outTransformation);
    }

从一二节我们发现:自定义视图动画的主要逻辑是重写applyTranformation方法而自定义插值器的主要逻辑是重写getInterpolation
方法,然而从上面的final float interpolatedTime = mInterpolator.getInterpolation(normalizedTime);applyTransformation(interpolatedTime, outTransformation);这两行代码可以得知插值器的getInterpolator的返回值作为
applyTransformation的第一个参数。他们的引用关系是知道了?但是这两个方法的参数是如何得到的呢,有什么作用呢?
1)由上面的代码块可知getInterpolation的参数normalizedTime是其实就是已完成的时间跟总时长的比,所以取值范围是0~1,
我们可以通过某个函数并根据normalizedTime的值去运算得到一个有特定规律的值序列,就像是一些三角函数之类的。
2)而在applyTransformation方法中接收到对应的由getInterpolator计算出来的值后,结合第一个参数就可以实现一些特定的效果了。

4、举例:DecelerateInterpolator:
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;
我们假如直接使用默认构造方法则mFactor=1.0f,由此可知返回值是由小到大的,并且变化速率越来越小;
TranslationAnimation:
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
    float dx = mFromXDelta;
    float dy = mFromYDelta;
    if (mFromXDelta != mToXDelta) {
        dx = mFromXDelta + ((mToXDelta - mFromXDelta) * interpolatedTime);
    }
    if (mFromYDelta != mToYDelta) {
        dy = mFromYDelta + ((mToYDelta - mFromYDelta) * interpolatedTime);
    }
    t.getMatrix().setTranslate(dx, dy);
}
dx = mFromXDelta + ((mToXDelta - mFromXDelta) * interpolatedTime);可以发现dx是与interpolatedTime成正比的;
再加上DecelerateInterpolator的getInterpolation返回值的增长速度是从块变慢的,所以就实现了TranslationAnimation动画的
是平移量是增加的,只是增加的速度变慢的。
示例分析总结:根据对DecelerateInterpolator和TranslationAnimation的源代码解析自定义插值器的返回值一般都是增长的只是
增长的速率可以是由慢变快(AccelerateInterpolator)和由快变慢(DecelerateInterpolator等,而自定义动画的效果变化量一般
interpolatedTime参数成正比



warn:一开始我在认识插值器的时候发现他的核心方法是getInterpolator的时候,结合他的参数input和TranslationAnimation等系统
实现的animation类,以为getInterpolator的参数就是TransitionAnimation的fromXDelta和toXDelta之间的某个值,这是非常错误的。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值