基于Android R版本分析
Animation
上一章节,我们分析了ValueAnimator和ObjectAnimator的一些概念和使用流程;
本章节,我们着重分析ValueAnimator的工作原理;
android中的属性动画的实现是通过不断的改变View的属性然后刷新,这个改变过程是通过数据的连续补帧和渐变来实现的,那么这个就需要有个脉冲的类来实现这个功能,而且这个脉冲不是随便写的,必须要根据硬件的配置和设置已经硬件环境来触发,这个过程中有个重要的实现类就是ValueAnimator;
ValueAnimator 继承关系
-
Animator:属性动画的基类,这个是一个抽象类,是一个基础框架类,里面定义个很多的规范方法,需要子类实现,比如动画的开始、动画的暂停、动画的结束、动画的模式、动画持续时间等方法;
-
valueAnimator:属性动画的核心类,这个类里面主要完成了:
- 脉冲回调机制
- 对属性动画的开始、暂停、设置参数等做了逻辑实现
这个类可以用来实现自定义的属性动画比较多,不限于View的,比如实现Paint的draw不是基于View本身的,画一个圆,就可以用这个完成,扩展性非常高;
-
ObjectAnimator:继承于ValueAnimator的,在此基础上,主要针对View的动画做了方便处理,可以直接对View的set、get 属性直接做动画,更加方便直接;
-
AnimatorSet:对多个动画Animator进行按照一定的顺序执行的类,通俗的说是一个组合动画,以此来实现更加复杂的动画的目的;
ValueAnimator 脉冲
- 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()方法讲解;
这个过程中,其实核心逻辑就是构建了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的状态情况,包括 start、end、cancel、repeat 4种状态;
ValueAnimator start
valueAnimator.start();
这个过程就是Animator中最核心的逻辑;
整个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
整个add Animation Callback过程执行了3件事:
- ValueAnimator向Choreographer中注入action = FrameCallback,可以简单的理解为将ValueAnimator和Choreographer关联起来,后续Choreographer会通过FrameCallbac访问到ValueAnimator中;
- ValueAnimator向AnimationHandler注册AnimationFrameCallback,ValueAnimator本身实现了AnimationFrameCallback接口类,在后续的Callback回调中,Choreographer会通过FrameCallback调用到AnimationFrameCallback;
- 通过Choreographer中的FrameDisplayEventReceiver,调用nativeScheduleVsync() 函数,监听底层驱动层的Vsync信号的上报;
doFrame
在addAnimationCallback()过程中,我们通过nativeScheduleVsync()函数监听底层驱动的Vsync信号上报,当Vsync信号上报之后,会调用DisplayEventReceiver的dispatchVsync()方法分发Vsync数据,Choreographer中FrameDisplayEventReceiver实现了DisplayEventReceiver,所以会执行回FrameDisplayEventReceiver中;
在整个过程中,其实只是针对一帧Frame的数据处理响应过程,在最后会循环调用postFrameCallback()方法继续响应下一帧数据的Vsync上报;
我们针对一帧Frame数据响应进行分析,在该过程中基本上执行了3件事情:
- 通过调用animateValue()方法计算出当前的动画值并调用应用侧注册的listener将该动画值回调到应用层;
- 判断当前动画是否已经结束,这个只存在于最后一帧动画Frame的时候,在该场景下,需要将mAnimationCallbacks集合中保存的AnimationFrameCallback置位null,但是暂时不移除对应的id,然后通过AnimatorListenerAdapter告知应用层Animation已结束;
- 最后通过cleanUpList遍历mAnimationCallbacks集合,将其中id值对应的AnimationFrameCallback为null的元素移除;