ViewRoot 和 DecorView 简介

ViewRoot 对应于 ViewRootImpl 类,他是链接WindowManager 和 DecorView 的纽带,View 的三大流程均是通过 ViewRoot 来完成的。在ActivityThread 中,当 Activity 对象呗创建完毕后,会将 DecorView 添加到 Window 中,同时会创建 ViewRootImpl 对象,并将 ViewRootImpl  和 DecorView 建立联系,这个过程可以看如下代码:
        root = new ViewRootImpl(view.getContext(), display);
        root.setView(view, wparams, panelParentView);
View 的绘制流程是从 ViewRoot 的 performTraversals 方法开始的,他经过 measure,layout,draw 三个过程才能最终将一个 View 绘制出来,其中 measure 是用来测量 View 的宽和高,layout 是用来确定 View 在父容器中的放置位置,draw 则负责将 View 绘制在屏幕上。针对 performTraversals 的大致流程,可以使用下图表示:

根据上图所示,performTraversals 会依次调用 performMeasure, performLayout 和 performDraw 三个方法,这三个方法分别完成顶级的 View 的 measure,layout,draw 这三大流程,其中 performMeasure 会调用 measure 方法,在 measure 中又会调用 onMeasure,在 onMeasure 中则会调用对所有的子元素进行 measure 过程,这个时候 measure 流程就从父元素转传递到子元素了,这样就完成了一次 measure 过程。接着子元素会重复父元容器的 measure 过程,如此反复完成整个 View 树的遍历。同理,performLayout  和 performDraw 的传递流程和 performMeasure 是类似的,唯一不同的是,performDraw 的传递过程是在 draw 方法中通过 dispatchDraw 来实现的,不过这没有本质的区别。

measure 过程决定了 View 的宽高,measure 完成之后,可以通过 getMeasureWidth 和 getMeasureHeight 方法来获取 View 测量后的宽高,在几乎所有情况下它都等于 View 最终的宽高,但是特殊情况除外,这点以后会进行讲解。layout 过程决定了 View 的四个顶点的坐标和实际的 View  宽高,完成以后,可以通过getTop,getBottom,getLeft,getRight 来拿到 View 的四个顶点位置,并可以通过 getWidth 和 getHeight 方法来拿到 View 的最终宽高。Draw 决定 View 的显示,只有 draw 方法完成以后 View 的内容才能呈现在屏幕上。

猜你喜欢

转载自blog.csdn.net/sinat_29874521/article/details/79993615