Android -- Interpolator

Interpolator 被用来修饰动画效果,定义动画的变化率,可以使存在的动画效果accelerated(加速),decelerated(减速),repeated(重复),bounced(弹跳)等。

AccelerateDecelerateInterpolator 在动画开始与结束的地方速率改变比较慢,在中间的时候加速
AccelerateInterpolator 在动画开始的地方速率改变比较慢,然后开始加速
AnticipateInterpolator 开始的时候向后然后向前甩
AnticipateOvershootInterpolator 开始的时候向后然后向前甩一定值后返回最后的值
BounceInterpolator 动画结束的时候弹起
CycleInterpolator 动画循环播放特定的次数,速率改变沿着正弦曲线
DecelerateInterpolator 在动画开始的地方快然后慢
LinearInterpolator 以常量速率改变
OvershootInterpolator 向前甩一定值后再回到原来位置

如果android定义的interpolators不符合你的效果也可以自定义interpolators

Interpolator接口

package android.animation;
 
/**
 * 时间插值器定义了一个动画的变化率。
 * 这让动画让非线性的移动轨迹,例如加速和减速。
 */
public interface TimeInterpolator {
 
    /**
     * 将动画已经消耗的时间的分数映射到一个表示插值的分数。
     * 然后将插值与动画的变化值相乘来推导出当前已经过去的动画时间的动画变化量。
     *
     * @param input  一个0到1.0表示动画当前点的值,0表示开头。1表示结尾
     * @return   插值。它的值可以大于1来超出目标值,也小于0来空破底线。
     */
    float getInterpolation(float input);
}

TimeInterpolator是在Android API11时加入的之前类就叫Interpolator。

package android.view.animation;
 
import android.animation.TimeInterpolator;
 
/**
 * 
 * 一个定义动画变化率的插值器。
 * 它允许对基本的(如透明,缩放,平移,旋转)进行加速,减速,重复等动画效果
 */
public interface Interpolator extends TimeInterpolator {
    // A new interface, TimeInterpolator, was introduced for the new android.animation
    // package. This older Interpolator interface extends TimeInterpolator so that users of
    // the new Animator-based animations can use either the old Interpolator implementations or
    // new classes that implement TimeInterpolator directly.
}

AccelerateInterpolator

/**
 * 一个开始很慢然后不断加速的插值器。
 */
public class AccelerateInterpolator implements Interpolator {
    private final float mFactor;
    private final double mDoubleFactor;
 
    public AccelerateInterpolator() {
        mFactor = 1.0f;
        mDoubleFactor = 2.0;
    }
 
    /**
     * 
     * @param factor 
     *     动画的快慢度。将factor设置为1.0f会产生一条y=x^2的抛物线。
增加factor到1.0f之后为加大这种渐入效果(也就是说它开头更加慢,结尾更加快)
     */
    public AccelerateInterpolator(float factor) {
        mFactor = factor;
        mDoubleFactor = 2 * mFactor;
    }
 
    public AccelerateInterpolator(Context context, AttributeSet attrs) {
        TypedArray a =
                context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.AccelerateInterpolator);
 
        mFactor = a.getFloat(com.android.internal.R.styleable.AccelerateInterpolator_factor, 1.0f);
        mDoubleFactor = 2 * mFactor;
 
        a.recycle();
    }
 
    @Override
    public float getInterpolation(float input) {
        if (mFactor == 1.0f) {
            return input * input;
        } else {
            return (float)Math.pow(input, mDoubleFactor);
        }
    }
}

加速的快慢度由参数fractor决定。当fractor值为1.0f时,动画加速轨迹相当于一条y=x^2的抛物线。

技术分享

当fractor不为1时,轨迹曲线是y=x^(2*fractor)(0<x<=1)的曲线。(当fractor为4时)

技术分享

如果你在使用AccelerateInterpolator时,想要那种一开始很慢,然后突然就很快的加速的动画效果的话,就将fractor设置大点。

DecelerateInterpolator

/**
 * 一个开始比较快然后减速的插值器
 *
 */
public class DecelerateInterpolator implements Interpolator {
    public DecelerateInterpolator() {
    }
 
    /**
     * 
     * @param factor
     *        动画的快慢度。将factor值设置为1.0f时将产生一条从上向下的y=x^2抛物线。
     *        增加factor到1.0f以上将使渐入的效果增强(也就是说,开头更快,结尾更慢)
     */
    public DecelerateInterpolator(float factor) {
        mFactor = factor;
    }
 
    public DecelerateInterpolator(Context context, AttributeSet attrs) {
        TypedArray a =
                context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.DecelerateInterpolator);
 
        mFactor = a.getFloat(com.android.internal.R.styleable.DecelerateInterpolator_factor, 1.0f);
 
        a.recycle();
    }
 
    @Override
    public float getInterpolation(float input) {
        float result;
        if (mFactor == 1.0f) {
            result = (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;
}

当fractor为1.0f。它减速的轨迹曲线为1-(1-x)^2。

技术分享

AccelerateDecelerateInterpolator

/**
 * 一个变化率开始慢从中间后开始变快。
 */
public class AccelerateDecelerateInterpolator implements Interpolator {
    public AccelerateDecelerateInterpolator() {
    }
 
    @SuppressWarnings({"UnusedDeclaration"})
    public AccelerateDecelerateInterpolator(Context context, AttributeSet attrs) {
    }
 
    @Override
    public float getInterpolation(float input) {
        return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
    }
}

技术分享

LinearInterpolator

public class LinearInterpolator implements Interpolator {
 
    public LinearInterpolator() {
    }
     
    public LinearInterpolator(Context context, AttributeSet attrs) {
    }
     
    public float getInterpolation(float input) {
        return input;
    }
}

BounceInterpolator

/**
 * 这个插值器的插值在后面呈弹跳状态。
 */
public class BounceInterpolator implements Interpolator {
    public BounceInterpolator() {
    }
 
    @SuppressWarnings({"UnusedDeclaration"})
    public BounceInterpolator(Context context, AttributeSet attrs) {
    }
 
    private static float bounce(float t) {
        return t * t * 8.0f;
    }
 
    @Override
    public float getInterpolation(float t) {
        // _b(t) = t * t * 8
        // bs(t) = _b(t) for t < 0.3535
        // bs(t) = _b(t - 0.54719) + 0.7 for t < 0.7408
        // bs(t) = _b(t - 0.8526) + 0.9 for t < 0.9644
        // bs(t) = _b(t - 1.0435) + 0.95 for t <= 1.0
        // b(t) = bs(t * 1.1226)
        t *= 1.1226f;
        if (t < 0.3535f) return bounce(t);
        else if (t < 0.7408f) return bounce(t - 0.54719f) + 0.7f;
        else if (t < 0.9644f) return bounce(t - 0.8526f) + 0.9f;
        else return bounce(t - 1.0435f) + 0.95f;
    }
}

技术分享

AnticipateInterpolator

/**
 * 一个开始向后荡,然后向前荡的插值器。
 */
public class AnticipateInterpolator implements Interpolator {
    private final float mTension;
 
    public AnticipateInterpolator() {
        mTension = 2.0f;
    }
 
    /**
     * @param tension 
     *  绷紧程度,当绷紧程序为0.0f时,也就没有了反向作用力。插值器将退化成一个y=x^3的加速插值器。
     */
    public AnticipateInterpolator(float tension) {
        mTension = tension;
    }
 
    public AnticipateInterpolator(Context context, AttributeSet attrs) {
        TypedArray a = context.obtainStyledAttributes(attrs,
                com.android.internal.R.styleable.AnticipateInterpolator);
 
        mTension =
                a.getFloat(com.android.internal.R.styleable.AnticipateInterpolator_tension, 2.0f);
 
        a.recycle();
    }
 
    @Override
    public float getInterpolation(float t) {
        // a(t) = t * t * ((tension + 1) * t - tension)
        return t * t * (((mTension + 1) * t) - mTension);
    }
}

技术分享

AnticipateOvershootInterpolator

/**
 * 一个插值器它开始向上推,然后向下荡,荡过最低线。然后再回到最低线。
 * <hr/>
 * An interpolator where the change starts backward then flings forward and overshoots
 * the target value and finally goes back to the final value.
 */
public class AnticipateOvershootInterpolator implements Interpolator {
    private final float mTension;
 
    public AnticipateOvershootInterpolator() {
        mTension = 2.0f * 1.5f;
    }
 
    /**
     * @param tension 
     *  anticipation/overshoot的比值。当和tension值为0.0f时,
     *  也就没有anticipation/overshoot的比值了,插值器退化为一个加速/减速插值器。
     */
    public AnticipateOvershootInterpolator(float tension) {
        mTension = tension * 1.5f;
    }
 
    /**
     * @param tension Amount of anticipation/overshoot. When tension equals 0.0f,
     *                there is no anticipation/overshoot and the interpolator becomes
     *                a simple acceleration/deceleration interpolator.
     * @param extraTension 
     * 乘以tension的值。例如,在上面构造函数中extraTension的值为1.5f
     */
    public AnticipateOvershootInterpolator(float tension, float extraTension) {
        mTension = tension * extraTension;
    }
 
    public AnticipateOvershootInterpolator(Context context, AttributeSet attrs) {
        TypedArray a = context.obtainStyledAttributes(attrs, AnticipateOvershootInterpolator);
 
        mTension = a.getFloat(AnticipateOvershootInterpolator_tension, 2.0f) *
                a.getFloat(AnticipateOvershootInterpolator_extraTension, 1.5f);
 
        a.recycle();
    }
 
    private static float a(float t, float s) {
        return t * t * (((s + 1) * t) - s);
    }
 
    private static float o(float t, float s) {
        return t * t * (((s + 1) * t) + s);
    }
 
    @Override
    public float getInterpolation(float t) {
        // a(t, s) = t * t * ((s + 1) * t - s)
                // o(t, s) = t * t * ((s + 1) * t + s)
        // f(t) = 0.5 * a(t * 2, tension * extraTension), when t < 0.5
        // f(t) = 0.5 * (o(t * 2 - 2, tension * extraTension) + 2), when t <= 1.0
        if (t < 0.5f) return 0.5f * a(t * 2.0f, mTension);
        else return 0.5f * (o((t * 2.0f) - 2.0f, mTension) + 2.0f);
    }
}

技术分享

CycleInterpolator

/**
 * 以指定的周期重复动画。变化率曲线为正弦。
 */
public class CycleInterpolator implements Interpolator {
    /**
     * 
     * @param cycles 要重复的周期数
     */
    public CycleInterpolator(float cycles) {
        mCycles = cycles;
    }
 
    public CycleInterpolator(Context context, AttributeSet attrs) {
        TypedArray a =
                context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.CycleInterpolator);
 
        mCycles = a.getFloat(com.android.internal.R.styleable.CycleInterpolator_cycles, 1.0f);
 
        a.recycle();
    }
 
    @Override
    public float getInterpolation(float input) {
        return (float)(Math.sin(2 * mCycles * Math.PI * input));
    }
 
    private float mCycles;
}

技术分享

OvershootInterpolator

/**
 * An interpolator where the change flings forward and overshoots the last value
 * then comes back.
 */
public class OvershootInterpolator implements Interpolator {
    private final float mTension;
 
    public OvershootInterpolator() {
        mTension = 2.0f;
    }
 
    /**
     * @param tension Amount of overshoot. When tension equals 0.0f, there is
     *                no overshoot and the interpolator becomes a simple
     *                deceleration interpolator.
     */
    public OvershootInterpolator(float tension) {
        mTension = tension;
    }
 
    public OvershootInterpolator(Context context, AttributeSet attrs) {
        TypedArray a = context.obtainStyledAttributes(attrs,
                com.android.internal.R.styleable.OvershootInterpolator);
 
        mTension =
                a.getFloat(com.android.internal.R.styleable.OvershootInterpolator_tension, 2.0f);
 
        a.recycle();
    }
 
    @Override
    public float getInterpolation(float t) {
        // _o(t) = t * t * ((tension + 1) * t + tension)
        // o(t) = _o(t - 1) + 1
        t -= 1.0f;
        return (t * t * (((mTension + 1) * t) + mTension)) + 1.0f;
        //plot {(x-1)(x-1)((tension+1)(x-1)+tension)+1,(0<x<=1)}
    }
}

当tension为默认值2时,

技术分享

 

我是天王盖地虎的分割线

 

参考:http://my.oschina.net/banxi/blog/135633

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