/** * * 原创作者: * 谷哥的小弟 http://blog.csdn.net/lfdfhl * * 文档描述: * View的draw过程源码分析 * * 绘制过程分为六步: * * 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) * * 其中第2步和第5步可以忽略,正如源码中所说的: * skip step 2 & 5 if possible (common case) * * 所以关注的是第1,3,4,6步. * */ public void draw(Canvas canvas) { if (ViewDebug.TRACE_HIERARCHY) { ViewDebug.trace(this, ViewDebug.HierarchyTraceType.DRAW); } final int privateFlags = mPrivateFlags; final boolean dirtyOpaque = (privateFlags & DIRTY_MASK) == DIRTY_OPAQUE && (mAttachInfo == null || !mAttachInfo.mIgnoreDirtyState); mPrivateFlags = (privateFlags & ~DIRTY_MASK) | DRAWN; /** * 第1步: * draw the background, if needed * 绘制View的背景 */ int saveCount; if (!dirtyOpaque) { final Drawable background = mBGDrawable; if (background != null) { final int scrollX = mScrollX; final int scrollY = mScrollY; if (mBackgroundSizeChanged) { background.setBounds(0, 0, mRight - mLeft, mBottom - mTop); mBackgroundSizeChanged = false; } if ((scrollX | scrollY) == 0) { background.draw(canvas); } else { canvas.translate(scrollX, scrollY); background.draw(canvas); canvas.translate(-scrollX, -scrollY); } } } /** * 第2,5步: * skip step 2 & 5 if possible (common case) * 忽略这两步. */ final int viewFlags = mViewFlags; boolean horizontalEdges = (viewFlags & FADING_EDGE_HORIZONTAL) != 0; boolean verticalEdges = (viewFlags & FADING_EDGE_VERTICAL) != 0; if (!verticalEdges && !horizontalEdges) { /** * 第3步: * draw the content * 调用onDraw()绘制View的内容 * 在View和ViewGroup的源码中onDraw方法均为空. * 因为每个View的内容不同,所以需要由具体的子类去实现 */ if (!dirtyOpaque) onDraw(canvas); /** * 第4步: * draw the children. * 调用dispatchDraw()绘制View的子View. * 在View中dispatchDraw()方法是一个空方法,因为View没有孩子. * 但是ViewGroup重写了该方法,因为ViewGroup有子View */ dispatchDraw(canvas); /** * 第6步: * draw decorations (scrollbars) * 绘制View的滚动条. * 其实View都是有滚动条的,但一般情况下将其隐藏了,没有显示 */ onDrawScrollBars(canvas); return; } //省略其余代码......... //省略其余代码......... //省略其余代码......... //省略其余代码......... }