简略理解Android View中的onMeasure和onLayout方法

本文仅简略地解释了onMeasure和onLayout的调用流程,不涉及调用过程中的参数意义的解释

假设当前Activity的页面层次架构如图[1]所示。一个LinearLayout中有两个TextView。

概述

总过程分两步:onMeasure过程和onLayout过程。onMeasure过程决定各个view的大小,onLayout过程决定view的位置。每个过程都从上往下地递归调用。

onMeasure过程

  • LinearLayout的父view/layout调用LinearLayout的measure方法,measure方法调用onMeasure方法。

  • onMeasure方法的目的是让layout(这里是LinearLayout)根据传入的两个MeasureSpec参数(代表父view当前分配给子view的Dimension),设置好自己‘想要’的Dimension大小

  • Linearlayout怎么知道自己“想要”多大呢?必须要先知道自己的子view的“想要”大小。于是它会调用各个子view的measure方法。当子View分配好自己的大小后,便开始计算自己的大小,最后调用setMeasuredDimension方法保存“想要”的Dimension。计算完毕后直接返回父View。

  • 值得注意的是,该过程(1-5)可能会调用多遍,来确认子view的大小(什么时候需要再次调用measure有待研究…)。

如图所示,LinearLayout首先要知道两个TextView的大小,然后根据结果调整自己的高度/宽度。

onLayout过程

  • LinearLayout的父view/layout调用LinearLayout的layout方法,layout方法调用onlayout方法。

  • 对于ViewGroup来说,onLayout方法的意义是“决定子view的具体位置”,即ViewGroup通过调用子view的layout方法,传入4个参数(top,left,right,bottom),子view应该按照这四个参数渲染自己(draw)。

如图所示,LinearLayout告诉第一个TextView它所在的位置。第二个TextView的位置应该是原位置加上第一个TextView的高度(还有一些边距等)。

最后

  • onMeasure和onLayout过程结束后,便开始递归调用onDraw方法渲染整个层次结构。
  • AbsoluteLayout的源码十分简单,可以参考它来学习上述两个方法。