1、View.startAnimation
public void startAnimation(Animation animation) {
animation.setStartTime(Animation.START_ON_FIRST_FRAME);
setAnimation(animation);
invalidateParentCaches();
invalidate(true);
}
setAnimation 将mCurrentAnimation设置为当前要执行的animation
invalidateParentCaches将当前view的mParent的flag设为 PFLAG_INVALIDATED
然后调用invalidate,同时参数为true,使当前view的缓存失效
2、View.invalidate
// Propagate the damage rectangle to the parent view.
final AttachInfo ai = mAttachInfo;
final ViewParent p = mParent;
if (p != null && ai != null && l < r && t < b) {
final Rect damage = ai.mTmpInvalRect;
damage.set(l, t, r, b);
p.invalidateChild(this, damage);
}
这里会将失效的矩阵传递给ViewParent,ViewParent的直接子类有ViewGroup和ViewRootImpl,通常情况下,view的直接parent是ViewGroup,所以接下来会进入ViewGroup.invalidateChild
3、ViewGroup.invalidateChild
在这个方法中
final boolean drawAnimation = (child.mPrivateFlags & PFLAG_DRAW_ANIMATION)
== PFLAG_DRAW_ANIMATION;
do {
View view = null;
if (parent instanceof View) {
view = (View) parent;
}
...
if (drawAnimation) {
if (view != null) {
view.mPrivateFlags |= PFLAG_DRAW_ANIMATION;
} else if (parent instanceof ViewRootImpl) {
((ViewRootImpl) parent).mIsAnimating = true;
}
}
// ...
parent = parent.invalidateChildInParent(location, dirty);
} while (parent != null);
这里会循环调用parent的invalidateChildInParent方法,在ViewGroup.invalidateChildInParent中,会返回它的mParent,但是最下层的ViewRootImpl.invalidateChildI