Android动画学习之属性动画(Property Animator)-2、属性动画执行流程

经过上一章的学习,我们已经学会了属性动画的基本使用,这一章里我们就来讲一讲属性动画的底层实现,简单讲一下什么是TimeInterpolator,什么是TypeEvaluator,以及它们是如何产生作用来呈现我们所看到的动画的。

Animator执行流程

我们从一个简单的例子来演示动画过程中的执行过程:

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    animator = ValueAnimator.ofFloat(0,800);
    animator.setDuration(2000);
    animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            ivContainer.setTranslationY((Float) animation.getAnimatedValue());
        }
    });

    rgInterpolatorType.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(RadioGroup group, int checkedId) {
            ivContainer.setTranslationY(0);
        }
    });
}

protected void valueAnalysis(View view) {
    log = new StringBuilder("");
    switch (rgInterpolatorType.getCheckedRadioButtonId()) {
        case R.id.rb_type_linear:
            animator.setInterpolator(new LinearInterpolator());//线性插值器
            break;
        case R.id.rb_type_accelerate_decelerate:
            animator.setInterpolator(new AccelerateDecelerateInterpolator());//先加速后减速
            break;
        case R.id.rb_type_bounce:
            animator.setInterpolator(new BounceInterpolator());//弹跳
            break;
    }
    animator.start();
}

程序执行效果是这样:

可以看到分别使用了三种不同的的Interpolator后,动画执行效果有了不同,LinearInterpolator为匀速执行,每个时间片段内变化值相同,AccelerateDecelerateInterpolator则是先加速再减速,最后一个则有一个回弹的效果,为什么会这样呢,我们点开LinearInterpolator和AccelerateDecelerateInterpolator,可以看到有两个有趣的方法:

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

我们这里直接讲结论了,此方法在属性动画的使用中是接收一个时间因子(当前动画执行时间/动画时长),然后返回一个float值(0~1),代表动画从开始到结束,然后返回值会被传入TypeEvaluator的evaluate(float fraction, Object startValue, Object endValue)方法中,充当第一个参数,然后根据开始值和结束值得出当前值(endValue - startValue)*fraction+startValue。这样也就不难理解AccelerateDecelerateInterpolator先加速后减速的原理了,看下余弦曲线π~2π的走势就可以很明了的知道了。BounceInterpolator由于我数学水平有限,就不献丑了,有兴趣的可以打开源码查看实现原理。

至此,我们已经明白一个动画的执行流程是如何的了。动画开始执行时,会动态的计算时间因子timeFraction(当前动画执行时间/动画时长),然后使用TimeInterpolator的getInterpolation方法得到一个合适的插值因子fraction,再由TypeEvaluator使用这个插值因子计算出当前的值(float、int、argb、object等),然后调用AnimatorUpdateListener的onAnimationUpdate方法,就可以取到当前的值了。而ObjectAnimator则是使用了反射的手段自动为我们传入的taeget设置了名为propertyName的属性值(使用setter和getter方法)。

最后列一些Animator中定义的方法,或者查看官方文档

Public methods
voidaddListener(Animator.AnimatorListener listener)添加动画监听
voidaddPauseListener(Animator.AnimatorPauseListener listener)添加动画暂停监听
voidcancel()取消动画
Animatorclone()返回一个当前动画的拷贝
voidend()结束动画
abstract longgetDuration()获取动画持续时间
TimeInterpolatorgetInterpolator()获取当前动画的插值器
ArrayList<Animator.AnimatorListener>getListeners()获取当前监听器列表
abstract longgetStartDelay()获取动画开始前延迟时间
longgetTotalDuration()获取当前动画的总时间,包括重复时间和延迟时间等
booleanisPaused()返回动画是否暂停
abstract booleanisRunning()返回当前动画是否正在执行
booleanisStarted()返回当前动画是否开始执行
voidpause()Pauses a running animation.
voidremoveAllListeners()移除所有监听器
voidremoveListener(Animator.AnimatorListener listener)移除指定监听器
voidremovePauseListener(Animator.AnimatorPauseListener listener)移除暂停监听
voidresume()将暂停动画继续执行
abstract AnimatorsetDuration(long duration)设置动画持续时间
abstract voidsetInterpolator(TimeInterpolator value)设置插值器
abstract voidsetStartDelay(long startDelay)设置动画开始前延迟
voidsetTarget(Object target)设置执行动画对象
voidsetupEndValues()设置动画结束值
voidsetupStartValues()设置动画开始值
voidstart()开始此动画

这篇就先这样,关于属性动画的底层执行逻辑,讲道理我理解的还不够,等以后知识储备能足以理解这一块的时候再回来重写吧。老规矩,代码地址:github
欢迎来我的博客讨论相关问题~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值