view 的绘制流程是从 ViewRoot 的 performTraversals 方法开始的, 它经过 measure,layout, 和 draw 三个过程才能最终将一个 View 绘制出来, 其中 measure 用来测量 View 发的宽和高, layout 用来确认 View 在父容器中的放置位置, 而 draw 则负责将 View 绘制在屏幕上.
performTraversals 方法
performTraversals 会一次调用 performMeasure,performLayut,performDraw 三个方法
2. 上面三个方法分别完成顶级 View 的 measure,layout 和 draw 这三大流程
其中在 perfomMeasure 中会调用 measure 方法
3. 在 measure 方法中又会调用 onMeasure 方法
4. 在 onMeasure 方法中则会对所有的子元素进行 measure 过程, 这个时候 measure 流程就从父容器传到子元素中了, 这样就完成了一次 measure 过程
5. 接着子元素会重复父容器的 measure 过程, 如此反复就完成了整个 View 树的遍历. 同理, performLayout 和 performDraw 的传递流程和 performMeasure 是类似的.
其中:
measure 过程决定了 View 的宽 / 高
measure 完成以后, 可以通过 getMeasuredWidth 和 getMeasuredHeight 方法来获取到 View 测量后的宽 / 高, 在几乎所有的情况下他都等同于 View 最终的宽 / 高
Layout 过程决定了 View 的四个顶点的坐标和实际的 View 的宽 / 高, 完成以后, 可以通过 getTop,getBottom,getRight,getLeft 拿到 View 四个顶点的位置, 并可以通过 getWidth 和 getHeight 方法来拿到 View 的最终宽 / 高.
Draw 过程则决定了 View 的显示, 只用 draw 方法完成以后 View 的内容才能呈现在屏幕上.
注:
getMeasuredWidth 和 getMeasuredHeight 方法获取的高度和宽度是 measure 过程中计算得到到, 所以要在 measure 之后调用.
getWidt() 获取的宽度 = right - left 这是 layout 之后才能确定, 所以 getWidth() 要在 layout 之后调用才能获取到值. 同理, getHeight()
来源: http://www.jianshu.com/p/8901ff51f67e