Android 插值器

本文深入解析了Android中动画插值器的工作原理,包括线性插值器LinearInterpolator、加速减速插值器AccelerateDecelerateInterpolator及自定义插值器DecelerateAccelerateInterpolator等。同时介绍了TimeInterpolator接口及TypeEvaluator类的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

插值器

看一下 Interpolator 与 TimeInterpolator ,发现了input

input值值变化范围是0-1,且随着动画进度(0% - 100% )均匀变化,即动画开始时,input值 = 0;动画结束时input = 1,

而中间的值则是随着动画的进度(0% - 100%)在0到1之间均匀增加​。

public interface TimeInterpolator {
    float getInterpolation(float input);
}
public interface Interpolator extends TimeInterpolator {
}

看一下系统自带的插值器 LinearInterpolator ,可以看到它的getInterpolation 方法直接返回了input ,所以是线性的。

public class LinearInterpolator extends BaseInterpolator implements NativeInterpolatorFactory {

    public LinearInterpolator() {
    }

    public LinearInterpolator(Context context, AttributeSet attrs) {
    }

    public float getInterpolation(float input) {
        return input;
    }

    /** @hide */
    @Override
    public long createNativeInterpolator() {
        return NativeInterpolatorFactoryHelper.createLinearInterpolator();
    }
}

 看一下系统自带的插值器 AccelerateDecelerateInterpolator ,可以看到它的getInterpolation 方法直接返回了

(float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f ,就如图这样,所以是先加速再减速的

public class AccelerateDecelerateInterpolator extends BaseInterpolator
        implements NativeInterpolatorFactory {
    public AccelerateDecelerateInterpolator() {
    }

    @SuppressWarnings({"UnusedDeclaration"})
    public AccelerateDecelerateInterpolator(Context context, AttributeSet attrs) {
    }

    public float getInterpolation(float input) {
        return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
    }

    /** @hide */
    @Override
    public long createNativeInterpolator() {
        return NativeInterpolatorFactoryHelper.createAccelerateDecelerateInterpolator();
    }
}

 自定义插值器

自定义先减速再加速的插值器,如图用的分段函数,所以是先减速再加速的

public class DecelerateAccelerateInterpolator implements TimeInterpolator {
    @Override
    public float getInterpolation(float input) {
        if (input <= 0.5)
            return (float) (Math.sin(input * Math.PI) / 2);
        else
            return (float) ((2 - Math.sin(input * Math.PI)) / 2);
    }
}

这样使用就行

btn1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                float curTranslationX = btn1.getTranslationX();
                Log.e("AnimActivity"," getTranslationX() : "+curTranslationX);
                // translationX 动画作用的对象的属性是X轴平移
                ObjectAnimator animator = ObjectAnimator.ofFloat(btn1,"translationX",curTranslationX,500,curTranslationX);
                animator.setDuration(1000);
                animator.setInterpolator(new DecelerateAccelerateInterpolator());
                animator.start();
            }
        });

TimeInterpolator 决定了动画从初始值过渡到结束值的节奏,可以看到其返回的是小数,是一个百分比,即动画值过度的百分比;

还有一个概念是估值器,TypeEvaluator  决定了属性值从初始值过渡到结束值的具体变化数值。

public class IntEvaluator implements TypeEvaluator<Integer> {

    // 参数分别为 估值小数,开始值,结束值
    public Integer evaluate(float fraction, Integer startValue, Integer endValue) {
        int startInt = startValue;
        // 可以看到返回值是 开始值 + 估值小数 * 差值
        return (int)(startInt + fraction * (endValue - startInt));
    }
}

参考 

https://blog.youkuaiyun.com/guolin_blog/article/details/43536355

https://www.jianshu.com/p/2f19fe1e3ca1

https://blog.youkuaiyun.com/dmk877/article/details/51550031

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值