rawChild(canvas, transientChild, drawingTime);
}
transientIndex++;
if (transientIndex >= transientCount) {
transientIndex = -1;
}
}
int childIndex = customOrder ? getChildDrawingOrder(childrenCount, i) : i;
final View child = (preorderedList == null)
? children[childIndex] : preorderedList.get(childIndex);
//如果子view没有进行隐藏操作,就准备调用该view/viewGroup的draw方法,然后又是新的一轮绘制,直到所有viewTree绘制完毕
if ((child.mViewFlags & VISIBILITY_MASK) == VISIBLE || child.getAnimation() != null) {
more |= drawChild(canvas, child, drawingTime);
}
}
//后边就是绘制完的一些小工作了.主要内容已经分析完了
while (transientIndex >= 0) {
// there may be additional transient views after the normal views
final View transientChild = mTransientViews.get(transientIndex);
if ((transientChild.mViewFlags & VISIBILITY_MASK) == VISIBLE ||
transientChild.getAnimation() != null) {
more |= drawChild(canvas, transientChild, drawingTime);
}
transientIndex++;
if (transientIndex >= transientCount) {
break;
}
}
if (preorderedList != null) preorderedList.clear();
// Draw any disappearing views that have animations
if (mDisappearingChildren != null) {
final ArrayList<View> disappearingChildren = mDisappearingChildren;
final int disappearingCount = disappearingChildren.size() - 1;
// Go backwards -- we may delete as animations finish
for (int i = disappearingCount; i >= 0; i--) {
final View child = disappearingChildren.get(i);
more |= drawChild(canvas, child, drawingTime);
}
}
if (usingRenderNodeProperties) canvas.insertInorderBarrier();
if (debugDraw()) {
onDebugDraw(canvas);
}
if (clipToPadding) {
canvas.restoreToCount(clipSaveCount);
}
// mGroupFlags might have been updated by drawChild()
flags = mGroupFlags;
if ((flags & FLAG_INVALIDATE_REQUIRED) == FLAG_INVALIDATE_REQUIRED) {
invalidate(true);
}
if ((flags & FLAG_ANIMATION_DONE) == 0 && (flags & FLAG_NOTIFY_ANIMATION_LISTENER) == 0 &&
mLayoutAnimationController.isDone() && !more) {
// We want to erase the drawing cache and notify the listener after the
// next frame is drawn because one extra invalidate() is caused by
// drawChild() after the animation is over
mGroupFlags |= FLAG_NOTIFY_ANIMATION_LISTENER;
final Runnable end = new Runnable() {
public void run() {
notifyAnimationListener();
}
};
post(end);
}
}
View的三部曲到此就分析完了,分析的不是那么细致,但是最少大体流程还是抛出来了。
在那遥远的ViewRootImpl中定义了一个叫做performTraversals函数,这个函数负责屏幕的显示工作
首先是由PhoneWindow来制作一个DecorView出来,在由WindowManager创建所对应的ViewRootImpl出来,然后调用ViewRootImpl下的setView函数
setView函数会触发requestLayout函数,这个函数会触发performTraversals函数,最终我们view的onMeasure onLayout onDraw都会被调用,从而完成了整个view的重绘过程
当屏幕上的任何一个地方发生变化。都是调用performTraversals来完成了。比如:钟表的分钟发生改变等等....有兴趣的朋友最好是自己在研读一遍源码,能学到很多有意思的功能
|