Drawing in ViewGroup. java starts from dispatchDraw (). The Canvas here is passed in by ViewRootImpl. java. At this time, the Canvas is the screen size Canvas.
@Override protected void dispatchDraw(Canvas canvas) {... more |= drawChild(canvas, child, drawingTime); }
protected boolean drawChild(Canvas canvas, View child, long drawingTime) { return child.draw(canvas, this, drawingTime); }
The drawChild function has only one sentence, pointing to the draw (Canvas canvas, ViewGroup parent, long drawingTime) function of View. java. (This function is different from the draw (Canvas canvas) function, where the View painting process starts)
boolean draw(Canvas canvas, ViewGroup parent, long drawingTime) {... int sx = 0; int sy = 0; if (!hasDisplayList) { computeScroll(); sx = mScrollX; sy = mScrollY; } final boolean hasNoCache = cache == null || hasDisplayList; final boolean offsetForScroll = cache == null && !hasDisplayList && layerType != LAYER_TYPE_HARDWARE; int restoreTo = -1; if (!useDisplayListProperties || transformToApply != null) { restoreTo = canvas.save(); } if (offsetForScroll) { canvas.translate(mLeft - sx, mTop - sy); } else { if (!useDisplayListProperties) { canvas.translate(mLeft, mTop); } if (scalingRequired) { if (useDisplayListProperties) { // TODO: Might not need this if we put everything inside the DL restoreTo = canvas.save(); } // mAttachInfo cannot be null, otherwise scalingRequired == false final float scale = 1.0f / mAttachInfo.mApplicationScale; canvas.scale(scale, scale); } }... if (!layerRendered) { if (!hasDisplayList) { // Fast path for layouts with no backgrounds if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) { mPrivateFlags &= ~PFLAG_DIRTY_MASK; if (DBG_DRAW) { Xlog.d(VIEW_LOG_TAG, "view draw1 : calling dispatchDraw,this = " + this); } dispatchDraw(canvas); } else { if (DBG_DRAW) { Xlog.d(VIEW_LOG_TAG, "view draw1 : calling draw,this = " + this); } draw(canvas); } } else { mPrivateFlags &= ~PFLAG_DIRTY_MASK; ((HardwareCanvas) canvas).drawDisplayList(displayList, null, flags);... }
The above Code contains two points to be pointed out: canvas. the translate () function indicates that the Canvas passed in by ViewRootImpl needs to be reduced according to the layout of the Child view, that is to say, the canvas of all the sub-Views on the screen is only a scaled canvas. Of course, this is why the coordinate origin of the sub-view canvas does not start from the upper left corner of the screen, it is the reason for its own size starting in the upper left corner.
The second thing to note is that if the sub-View of ViewGroup is still ViewGroup, it calls back dispatchDraw (canvas) for Division. If the sub-View is View, call the draw (canvas) function of the View to draw the image.