How View works draw

1, Overview

Compared with the previous measurement, the layout of the picture here is very simple

The general steps are as follows:

1. Draw background (canvas)

2. Draw yourself (onDraw)

3. Draw children(dispatchDraw)

4. Ondrawscrollbars

The following is the specific code of draw, which is divided into six parts, but the gradient edge is not necessarily there, so it is simplified to the above four steps.

    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;

        /*Here are the tips
         * 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)
         */
        //Step 1: draw the background
        // Step 1, draw the background, if needed
        int saveCount;

        if (!dirtyOpaque) {
            drawBackground(canvas);
        }
        //Step 2 and step 5: save and draw the gradient effect of the edge
        // 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) {
            //Step 3. Draw your own content
            // Step 3, draw the content
            if (!dirtyOpaque) onDraw(canvas);
            //Step 3. Picture child view
            // Step 4, draw the children
            dispatchDraw(canvas);

            // Overlay is part of the content and draws beneath Foreground
            if (mOverlay != null && !mOverlay.isEmpty()) {
                mOverlay.getOverlayView().dispatchDraw(canvas);
            }
            //Step 6: painting decoration
            // Step 6, draw decorations (foreground, scrollbars)
            onDrawForeground(canvas);

            // we're done...
            return;
        }
    }

2, Points for attention

ViewGroup is set to will by default for performance reasons_ NOT_ Drow, in this way, ondraw will not be executed. The specific code is as follows:

public ViewGroup(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
   super(context, attrs, defStyleAttr, defStyleRes);
    initViewGroup();
    initFromAttributes(context, attrs, defStyleAttr, defStyleRes);
}

private void initViewGroup() {
   // ViewGroup doesn't draw by default
    if (!debugDraw()) {
        setFlags(WILL_NOT_DRAW, DRAW_MASK);
    }
}

If we want to override the ondraw method of a viewgroup, we can call setWillNotDraw (false) in the constructor to remove its WILL_NOT_DRAW flag.

3, So far, View's measure, layout and draw have been analyzed from the source point of View. If you want to use it flexibly, there is no other way to write more by yourself. I will also try to build more wheels.

Posted on Sun, 24 May 2020 11:38:03 -0400 by vangelis