Choreographer
这个类来控制同步处理输入(Input)、动画(Animation)、绘制(Draw)三个UI操作
postCallback/postFrameCallback流程
将callback放入CallbackQueue中,请求Vsync信号,如果VSync信号到来,调用doFrame执行callbackQueue中的callback,执行顺序是:CALLBACK_INPUT,CALLBACK_ANIMATION,CALLBACK_TRAVERSAL,CALLBACK_COMMIT,然后就会执行post时候传进来的参数Runnable/FrameCallback
属性动画实现原理
// ValueAnimator
ValueAnimator valueAnimator = ValueAnimator.ofInt(0, 200, 100);
valueAnimator.setDuration(3000);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int currentValue = (Integer) animation.getAnimatedValue();
setX(currentValue);
}
});
valueAnimator.start();
- ValueAnimator.ofInt根据传入参数,初始化关键时间百分比对应的值,动画开始后计算属性值使用
- valueAnimator.start后,将ValueAnimator放入AnimationHandler 的callback列表中,AnimationHandler会向Choreographer提交这个callback,让这个动画在下一帧执行。
- 当前动画开始执行,开始计算属性值变化,通知监听器AnimatorUpdateListener,更新属性信息。如果是ObjectAnimator则通过反射调用“set+属性”,设置对象属性
- AnimationHandler判断当前是否有没执行完的动画,如果有继续给Choreographer发送执行动画请求
补间动画原理
View.startAnimation,动画开始重新绘制view以及他的父view,在draw方法中得到动画的变换矩阵,然后直接对canvas进行平移、旋转、缩放,透明度操作
补间动画只是对画布操作,并没有改变view 的任何属性(坐标长宽等),所以只能响应之前位置的输入事件,而属性动画改变了view的坐标,因此可以响应动画之后的位置上的输入事件
public void startAnimation(Animation animation) {
animation.setStartTime(Animation.START_ON_FIRST_FRAME);
setAnimation(animation);
invalidateParentCaches();
invalidate(true);
}
自定义动画必须重写applyTransformation方法实现动画动画效果,将与interpolatedTime时间点对应的变换矩阵存到参数t中,view绘制时(draw)会调用Animation.getTransformation从而对canvas进行操作。
class RotateAnimation extends Animation{
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
super.applyTransformation(interpolatedTime, t);
}
}
网友评论