View绘制过程(四)draw

View
public void draw(Canvas canvas) {

    //...

    /*
     * 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, if needed
    int saveCount;

    if (!dirtyOpaque) {
        drawBackground(canvas);
    }

    // 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 the content
        if (!dirtyOpaque) onDraw(canvas);

        // 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, draw decorations (foreground, scrollbars)
        onDrawForeground(canvas);

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

    /*
     * Here we do the full fledged routine...
     * (this is an uncommon case where speed matters less,
     * this is why we repeat some of the tests that have been
     * done above)
     */

    /
    // Step 2, save the canvas' layers
    
    //...

    // Step 3, draw the content
    if (!dirtyOpaque) onDraw(canvas);

    // Step 4, draw the children
    dispatchDraw(canvas);

    // Step 5, draw the fade effect and restore layers
    
    //...

    // Overlay is part of the content and draws beneath Foreground
    if (mOverlay != null && !mOverlay.isEmpty()) {
        mOverlay.getOverlayView().dispatchDraw(canvas);
    }

    // Step 6, draw decorations (foreground, scrollbars)
    onDrawForeground(canvas);
}

protected void onDraw(Canvas canvas) {}
protected void dispatchDraw(Canvas canvas) {}

流程:

  1. 绘制背景
  2. save the canvas' layers 准备用于绘制View在滑动时的边框渐变效果
  3. 绘制View的内容,onDraw(),是个空方法
  4. 调用dispatchDraw(),View类里是个空方法,ViewGroup类里会遍历所有child,调用child.draw()
  5. 绘制View在滑动时的边框渐变效果
  6. 绘制View的滚动条(可以看出所有的View都有滚动条)

总结:
自定义View基本只需重写onDraw()方法,其他5个步骤无需管理。关于onDraw(Canvas canvas)中的Canvas,可以另写一篇文章了。

你可能感兴趣的:(View绘制过程(四)draw)