欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android View 绘制流程(Draw)步骤详情

程序员文章站 2022-05-09 20:57:40
View的draw过程 以DecorView为例 Draw的过程依旧是从ViewRootImpl的performTraversals开始,进过一系列的调用,最终调用了View的...

View的draw过程
以DecorView为例
Draw的过程依旧是从ViewRootImpl的performTraversals开始,进过一系列的调用,最终调用了View的draw方法,由于ViewGroup没有重写draw方法,因此所有的View都是调用View#draw方法,因此,我们直接看它的源码

    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)
         */

        // 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;
        }
        。。。省略。。。
    }

View的绘制流程有一下六步骤:
1、对View的背景进行绘制:View.drawBackground
2、保存当前图层信息(可跳过)
3、绘制View的内容:View.OnDraw或者重写的OnDraw
4、对View的子View进行绘制(如果有子View):dispatchDraw 遍历调用所有子元素的draw方法。
5、绘制View的褪色的边缘,类似于阴影效果(可跳过)
6、绘制View的装饰:View.onDrawForeground