Animator - ValueAnimator工作机制分析

402 阅读6分钟

基于Android R版本分析

Animation

上一章节,我们分析了ValueAnimator和ObjectAnimator的一些概念和使用流程;

本章节,我们着重分析ValueAnimator的工作原理;

android中的属性动画的实现是通过不断的改变View的属性然后刷新,这个改变过程是通过数据的连续补帧和渐变来实现的,那么这个就需要有个脉冲的类来实现这个功能,而且这个脉冲不是随便写的,必须要根据硬件的配置和设置已经硬件环境来触发,这个过程中有个重要的实现类就是ValueAnimator;

ValueAnimator 继承关系

Animator继承.png

  • Animator:属性动画的基类,这个是一个抽象类,是一个基础框架类,里面定义个很多的规范方法,需要子类实现,比如动画的开始、动画的暂停、动画的结束、动画的模式、动画持续时间等方法;

  • valueAnimator:属性动画的核心类,这个类里面主要完成了:

    1. 脉冲回调机制
    2. 对属性动画的开始、暂停、设置参数等做了逻辑实现

    这个类可以用来实现自定义的属性动画比较多,不限于View的,比如实现Paint的draw不是基于View本身的,画一个圆,就可以用这个完成,扩展性非常高;

  • ObjectAnimator:继承于ValueAnimator的,在此基础上,主要针对View的动画做了方便处理,可以直接对View的set、get 属性直接做动画,更加方便直接;

  • AnimatorSet:对多个动画Animator进行按照一定的顺序执行的类,通俗的说是一个组合动画,以此来实现更加复杂的动画的目的;

ValueAnimator 脉冲

ValueAnimator脉冲.png

  • AnimationHandler:这个是对Choregrapher的包装类,对ValueAnimator提供了简易接口,AnimationHandler通过Choreographer实现脉冲回调;
  • ChoreograVspher:这个英文含义“编舞者”,通过向ServiceFlinger发送消息,然后经过处理后,ServiceFlinger向Choreographer发送Vsync信号,以此来统一系统的输入、视图绘制、动画的时机,所以这个实际是根据硬件的情况来输出的;

ValueAnimator 工作流程

// 构建ValueAnimator实例
ValueAnimator valueAnimator = new ValueAnimator();
// 设置动画的初始值过渡的结束值
valueAnimator.setIntValues(0, 100);
// 动画的持续时长
valueAnimator.setDuration(1500);
// 设置Interpolator, Interpolator被用来修饰动画效果, 定义动画的变化率
valueAnimator.setInterpolator(new OvershootInterpolator(1.0f));
// 设置动画的重复次数
valueAnimator.setRepeatCount(1);
// 设置动画的循环模式
//   ValueAnimator.RESTART:从结束位置反过来进行动画
//   ValueAnimator.INFINITE:从开始位置重新进行动画
valueAnimator.setRepeatMode(ValueAnimator.RESTART);
// 设置Animation监听器,通过回调的方式获取实时计算出来的变化值
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        int value = (Integer) animation.getAnimatedValue();
    }
});
// 设置Animator监听器,通过回调的方式获取Animator动画状态
valueAnimator.addListener(new AnimatorListenerAdapter() {
    @Override
    public void onAnimationCancel(Animator animation) {
    }
​
    @Override
    public void onAnimationEnd(Animator animation) {
    }
});
valueAnimator.start();

ValueAnimator 构建

// 构建ValueAnimator实例
ValueAnimator valueAnimator = new ValueAnimator();
// 设置动画的初始值过渡的结束值
valueAnimator.setIntValues(0, 100);

上述的构建方式本质上和ofXxx的方式是类同的,我们这边直接以ofXxx()方法讲解;

ValueAnimator_ofInt.png 这个过程中,其实核心逻辑就是构建了PropertyValuesHolder和KeyframeSet两个实例;

ValueAnimator 属性配置

// 动画的持续时长
valueAnimator.setDuration(1500);
// 设置Interpolator, Interpolator被用来修饰动画效果, 定义动画的变化率
valueAnimator.setInterpolator(new OvershootInterpolator(1.0f));
// 设置动画的重复次数
valueAnimator.setRepeatCount(1);
// 设置动画的循环模式
//   ValueAnimator.RESTART:从结束位置反过来进行动画
//   ValueAnimator.INFINITE:从开始位置重新进行动画
valueAnimator.setRepeatMode(ValueAnimator.RESTART);

这个部分基本上没有核心技术,就是简单的通过set()方法将配置的属性值赋值给ValueAnimator中的属性变量进行保存;

ValueAnimator Listener配置

// 设置Animation监听器,通过回调的方式获取实时计算出来的变化值
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        int value = (Integer) animation.getAnimatedValue();
    }
});
// 设置Animator监听器,通过回调的方式获取Animator动画状态
valueAnimator.addListener(new AnimatorListenerAdapter() {
    @Override
    public void onAnimationCancel(Animator animation) {
    }
​
    @Override
    public void onAnimationEnd(Animator animation) {
    }
});

ValueAnimator包含了两种Listener:

  • AnimatorUpdateListener:这个主要是用于监听animation过程中动画的实时变化值;
  • AnimatorListenerAdapter:主要是用于监听animator的状态情况,包括 startendcancelrepeat 4种状态;

ValueAnimator start

valueAnimator.start();

这个过程就是Animator中最核心的逻辑;

ValueAnimator_start.png 整个start()过程中,大致可以分为两部分:

  • addAnimationCallback:这个是核心逻辑,不能通过方法名来简单的判断该方法作用,这个方法是实现动画播放的逻辑;
  • startAnimationCallback:这个并不是start Animation,其中只是用于initAnimation,同时将mRunning变量赋值为true,代表后续可以进行animation的绘制播放以及通过notify向注册监听的listener上报开始的状态情况;

在start()过程中,还涉及到了几个状态值:

  • mStarted = true;:代表Animator是否已经开始状态;
  • mPaused = false;:代表Animator是否处于暂定状态;
  • mRunning = false;:代表Animator是否已经处于运行播放状态;
  • mAnimationEndRequested = false;:代表Animator是否已经播放结束

mRunning这个变量是比较核心的,它涉及到了后续的animation是否可以正常绘制;

addAnimationCallback

addAnimationCallback.png 整个add Animation Callback过程执行了3件事:

  • ValueAnimatorChoreographer中注入action = FrameCallback,可以简单的理解为将ValueAnimator和Choreographer关联起来,后续Choreographer会通过FrameCallbac访问到ValueAnimator中;
  • ValueAnimatorAnimationHandler注册AnimationFrameCallback,ValueAnimator本身实现了AnimationFrameCallback接口类,在后续的Callback回调中,Choreographer会通过FrameCallback调用到AnimationFrameCallback;
  • 通过Choreographer中的FrameDisplayEventReceiver,调用nativeScheduleVsync() 函数,监听底层驱动层的Vsync信号的上报;
doFrame

在addAnimationCallback()过程中,我们通过nativeScheduleVsync()函数监听底层驱动的Vsync信号上报,当Vsync信号上报之后,会调用DisplayEventReceiver的dispatchVsync()方法分发Vsync数据,Choreographer中FrameDisplayEventReceiver实现了DisplayEventReceiver,所以会执行回FrameDisplayEventReceiver中;

ValueAnimator_doFrame.png 在整个过程中,其实只是针对一帧Frame的数据处理响应过程,在最后会循环调用postFrameCallback()方法继续响应下一帧数据的Vsync上报;

我们针对一帧Frame数据响应进行分析,在该过程中基本上执行了3件事情:

  • 通过调用animateValue()方法计算出当前的动画值并调用应用侧注册的listener将该动画值回调到应用层;
  • 判断当前动画是否已经结束,这个只存在于最后一帧动画Frame的时候,在该场景下,需要将mAnimationCallbacks集合中保存的AnimationFrameCallback置位null,但是暂时不移除对应的id,然后通过AnimatorListenerAdapter告知应用层Animation已结束;
  • 最后通过cleanUpList遍历mAnimationCallbacks集合,将其中id值对应的AnimationFrameCallback为null的元素移除;