一、开始
调用View.startAnimation开始运行动画。
public void startAnimation(Animation animation) {
animation.setStartTime(Animation.START_ON_FIRST_FRAME);
setAnimation(animation);
invalidateParentCaches();
invalidate(true);
}
这个方法很简单,主要做了两件事: 1. 将动画赋值给当前View的mCurrentAnimation变量; 2. 标记当前的View需要重绘;
二、运行中
2.1 前期
在Choreographer接收到vsync信号后,回调给ViewRootImpl,开始刷新界面。 经过一系列的调用,最终,会进入到View的draw(Canvas canvas, ViewGroup parent, long drawingTime)方法中。 这个过程比较长,涉及到的类有Choreographer -> ViewRootImpl -> ThreadRenderer -> ViewGroup -> View。
2.2 View
View的draw(Canvas canvas, ViewGroup parent, long drawingTime)方法会调用applyLegacyAnimation方法,该方法又会调用Animation的getTransformation方法。
2.3 Animation
在Animation.getTransformation中,会进行一系列的处理,将当前时间根据设置的插值器转换为插值时间,并最终调用applyTransformation方法。这是动画实现核心逻辑的地方。根据applyTransformation的具体实现,就可以完成动画在当前帧的动作。
applyTransformation接收2个参数,第一个是插值时间,相当于动画完成的百分比;第二个是一个Transformation对象,通过操作这个对象来实现动画。
例如,AlphaAnimation.applyTransformation方法实现如下:
protected void applyTransformation(float interpolatedTime, Transformation t) {
final float alpha = mFromAlpha;
t.setAlpha(alpha + ((mToAlpha - alpha) * interpolatedTime));
}
ScaleAnimation.applyTransformation方法实现如下:
protected void applyTransformation(float interpolatedTime, Transformation t) {
float sx = 1.0f;
float sy = 1.0f;
float scale = getScaleFactor();
if (mFromX != 1.0f || mToX != 1.0f) {
sx = mFromX + ((mToX - mFromX) * interpolatedTime);
}
if (mFromY != 1.0f || mToY != 1.0f) {
sy = mFromY + ((mToY - mFromY) * interpolatedTime);
}
if (mPivotX == 0 && mPivotY == 0) {
t.getMatrix().setScale(sx, sy);
} else {
t.getMatrix().setScale(sx, sy, scale * mPivotX, scale * mPivotY);
}
}
三、结束
在 2.2 中的applyLegacyAnimation方法会返回一个boolean值,标记了动画是否还要继续执行。如果该值为false,表示动画需要结束。 如果标记需要结束动画,则View会执行parent.finishAnimatingView方法。在其父布局中,又会调用view.clearAnimation方法。也就是说,最终调用的是View的clearAnimation方法。在其中,会将mCurrentAnimation变量置为null。
四、总结
1. Choreographer类会监听设备的vsync信号,在每一帧刷新的时候,收到回调。 2. 当收到回调后,Choreographer会通知ViewRootImpl刷新视图树。 3. 刷新视图树会调用View.draw(canvas, parent, time)方法。 4. View.draw(canvas, parent, time)最终会调用Animation.getTransformation方法。 5. Animation的getTransformation中会调用applyTransformation方法,Animation子类在其中完成动画的具体实现。