Android UI的绘制流程

本文详细介绍了Android UI的绘制流程,包括ViewRootImpl类中的performTraversals()方法如何触发View的measure()、layout()和draw()方法,完成整个绘制流程。测量、布局和绘制的具体步骤也进行了说明。

ViewRootImpl类

ViewRootImpl 类是连接 WindowManager 和 DecorView 的纽带。ActivityThread 中当 activity 对象被创建好后,会将 DecorView 加入到 Window中,同时完成 ViewRootImpl 的创建并建立和 DecorView 的联系。

root = new ViewRootImpl(view.getContext(), display);
root.setView(view, wparams, panelParentView);

View的绘制是由Android系统的ViewRootImpl类中的performTraversals()方法触发的。通过ViewRootImpl类的performTraversals()方法,系统会依次调用View的measure()、layout()和draw()方法,完成View的绘制流程。
代码省略如下:

    private void performTraversals() {
        // Ask host how big it wants to be
        performMeasure(childWidthMeasureSpec, childHeightMeasureSpec);
        performLayout(lp, mWidth, mHeight);
        if (!performDraw() && mActiveSurfaceSyncGroup != null) {
            mActiveSurfaceSyncGroup.markSyncReady();
        }
    }

测量流程

在这里插入图片描述
在performMeasure()方法中,通过遍历View树,调用每个View的measure()方法来进行测量操作。

布局流程

在这里插入图片描述
在performLayout()方法中,通过遍历View树,调用每个View的layout()方法来进行布局操作。

绘制流程

在这里插入图片描述
在performDraw()方法中,首先创建一个Canvas对象,并清空画布。然后,通过遍历View树,调用每个View的draw()方法来执行实际的绘制操作。最后,解锁画布并提交绘制结果。最开始生成的画布会一直传给每一个子View来绘制。
对于绘制这里说一句:
View的绘制过程遵循如下几步;
①绘制背景 background.draw(canvas)
②绘制自己(onDraw)
③绘制Children(dispatchDraw)
④绘制滚动条和前景色(onDrawForeground)
⑤绘制高亮线(drawDefaultFocusHighlight)

    public void draw(@NonNull Canvas canvas) {
        final int privateFlags = mPrivateFlags;
        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)
         *      7. If necessary, draw the default focus highlight
         */

        // Step 1, draw the background, if needed
        int saveCount;

        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
            onDraw(canvas);

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

            drawAutofilledHighlight(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);

            // Step 7, draw the default focus highlight
            drawDefaultFocusHighlight(canvas);

            if (isShowingLayoutBounds()) {
                debugDrawFocus(canvas);
            }

            // we're done...
            return;
        }
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值