美文网首页
View Draw 简要过程

View Draw 简要过程

作者: zhaoyubetter | 来源:发表于2016-11-27 16:31 被阅读58次

    draw 就是将view绘制到屏幕上,一般有如下步骤:

    1. 绘制其背景(backgroupDrawable.draw(canvas));
    2. 绘制自己(onDraw);
    3. 绘制子view(dispatchDraw)
    4. 绘制装饰(onDrawScrollBars)

    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的绘制过程传递 通过 dispatchDraw方法来实现,dispatchDraw遍历调用所有子view元素的draw方法,这样draw事件就传递下去;

    setWillNotDraw 方法

    /**
         * If this view doesn't do any drawing on its own, set this flag to
         * allow further optimizations. By default, this flag is not set on
         * View, but could be set on some View subclasses such as ViewGroup.
         *
         * Typically, if you override {@link #onDraw(android.graphics.Canvas)}
         * you should clear this flag.
         *
         * @param willNotDraw whether or not this View draw on its own
         */
        public void setWillNotDraw(boolean willNotDraw) {
            setFlags(willNotDraw ? WILL_NOT_DRAW : 0, DRAW_MASK);
        }
    

    如果View不需要绘制任何内容,可设置此标记为true,系统会进行相关优化;
    默认情况下,view没有启动此标志,但viewgroup默认启动这个优化标志,
    实际操作场景是:当自定义控件继承自viewgroup,且本身不具备绘制功能时,就可开启此标记,便于系统优化;viewGroup 需要draw时,也得显示的关闭WILL_NOT_DRAW这个标记位;

    相关文章

      网友评论

          本文标题:View Draw 简要过程

          本文链接:https://www.haomeiwen.com/subject/kqrnpttx.html