@CallSuper public void draw(Canvas canvas) { final int privateFlags = mPrivateFlags; final boolean dirtyOpaque = (privateFlags & PFLAG_DIRTY_MASK) == PFLAG_DIRTY_OPAQUE && (mAttachInfo == null || !mAttachInfo.mIgnoreDirtyState); mPrivateFlags = (privateFlags & ~PFLAG_DIRTY_MASK) | PFLAG_DRAWN; /* * Draw traversal performs several drawing steps which must be executed * in the appropriate order: * * 1. Draw the background * 2. If necessary, save the canvas‘ layers to prepare for fading * 3. Draw view‘s content * 4. Draw children * 5. If necessary, draw the fading edges and restore layers * 6. Draw decorations (scrollbars for instance) */ //第一步,绘制背景 //在第一步中,在drawBackground中会根据不同类型的背景,去调用不同类型下的draw方法 //比如,背景是一个BitmapDrawable,那么就会调用BitmapDrawable的draw方法,这些都是用Drawable这个抽象类编写的 saveCount; if (!dirtyOpaque) { drawBackground(canvas); } viewFlags = mViewFlags; boolean horizontalEdges = (viewFlags & FADING_EDGE_HORIZONTAL) != 0; boolean verticalEdges = (viewFlags & FADING_EDGE_VERTICAL) != 0; if (!verticalEdges && !horizontalEdges) { (!dirtyOpaque) onDraw(canvas); // 调用ViewGroup的dispatchDraw方法,让ViewGroup遍历并调用所有的onDraw方法,整个view绘画流程被激活 dispatchDraw(canvas); (mOverlay != null && !mOverlay.isEmpty()) { mOverlay.getOverlayView().dispatchDraw(canvas); } // 绘制前景图 onDrawForeground(canvas); ; } /* * 后边是对于Fading Edge效果的设置,这次就不再分析了,有兴趣的朋友可以自己看一下这个效果 * */ }
剩下的流程就是view树中各个子view自己的绘制流程了,然后ViewRootImpl在拿着绘制好的画布
View的三部曲到此就分析完了,分析的不是那么细致,但是最少大体流程还是抛出来了。
在那遥远的ViewRootImpl中定义了一个叫做performTraversals函数,这个函数负责屏幕的显示工作
首先是由PhoneWindow来制作一个DecorView出来,在由WindowManager创建所对应的ViewRootImpl出来,然后调用ViewRootImpl下的setView函数
setView函数会触发requestLayout函数,这个函数会触发performTraversals函数,最终我们view的onMeasure onLayout onDraw都会被调用,从而完成了整个view的重绘过程
当屏幕上的任何一个地方发生变化。都是调用performTraversals来完成了。比如:钟表的分钟发生改变等等....有兴趣的朋友最好是自己在研读一遍源码,能学到很多有意思的功能
[Android FrameWork 6.0源码学习] View的重绘过程之Draw