onFinishInflate() 当View中所有的子控件 均被映射成xml后触发
onMeasure(int, int) 确定所有子元素的大小
onLayout(boolean, int, int, int, int) 当View分配所有的子元素的大小和位置时触发
onSizeChanged(int, int, int, int) 当view的大小发生变化时触发
一旦执行过onMeasure,往往就会执行onLayout来重新布局
二,实例展示:
android:id="@+id/root_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
android:id="@+id/bottom_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="bottom"
android:orientation="vertical" >
android:id="@+id/button"
android:layout_width="fill_parent"
android:layout_height="100dp"
android:text="haha" >
android:id="@+id/textview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#77777777"
android:text="hello" />
上面是一些自定的view ,并重载了一个方法,打log分析:
按照上面的层次关系,每个view自定义一下,就是为了将三个方法打印出来,打印结果:
01-19 17:17:44.985: I/cdd(15351):
ReSizeLayout--------onSizeChanged--480,741,0,0
01-19 17:17:44.985: I/cdd(15351):
MyEditText--------onSizeChanged--480,65,0,0
01-19 17:17:44.985: I/cdd(15351):
MyEditText--------onLayout--0,0,480,65
01-19 17:17:44.985: I/cdd(15351):
MyLinearLayout--------onSizeChanged--480,676,0,0
01-19 17:17:44.985: I/cdd(15351):
MyTextView--------onSizeChanged--480,25,0,0
01-19 17:17:44.985: I/cdd(15351):
MyTextView--------onLayout--0,651,480,676
01-19 17:17:44.985: I/cdd(15351):
MyLinearLayout--------onLayout--0,65,480,741
01-19 17:17:44.985: I/cdd(15351):
ReSizeLayout--------onLayout--0,0,480,741
01-19 17:17:44.985: I/cdd(15351):
MyEditText--------onMeasure--480,741
01-19 17:17:44.985: I/cdd(15351):
MyTextView--------onMeasure--480,526
01-19 17:17:44.985: I/cdd(15351):
MyLinearLayout--------onMeasure--480,676
01-19 17:17:44.985: I/cdd(15351):
ReSizeLayout--------onMeasure--480,741
01-19 17:17:44.985: I/cdd(15351):
MyEditText--------onLayout--0,0,480,65
01-19 17:17:44.985: I/cdd(15351):
MyTextView--------onLayout--0,651,480,676
01-19 17:17:44.985: I/cdd(15351):
MyLinearLayout--------onLayout--0,65,480,741
01-19 17:17:44.995: I/cdd(15351):
ReSizeLayout--------onLayout--0,0,480,741
感觉执行顺序是这样的:
1. 首先是执行叶子child的onMeasure方法,逐层向上调用,最后调用到root的onMeasure,onMeasure本身的作用就是告诉父亲自己占用多大的位置,根据递归原理,onMeasure的确应该从下往上层调用
2. 调用到root的onMeasure后,其实这个统计大小的工作肯定是比root还高级别的View触发,也许就是DecorView,统计完大小后,开始调用onSizeChange,我想这里调用onSizeChange是因为首次显示的原因,调用onSizeChange是从root开始的,然后逐级调用到child,调用每个child的onSizeChange完毕后,每个child执行layout动作
3. 从顺序来看,layout动作和onMeasure一样,都是从小往上层调用。从叶子child的onlayout调用开始,最后调用到root的onlayout方法。因为只有大小发生了变化才会执行onSizeChange,所以没有onSizeChange的时候,就是从尾到头执行完onmeasure,再开始从尾到头执行完onlayout
4. 由此看来,onSizeChange并不一定会调用,只有View的大小发生变化才会调用,而且也不一定一定从root开始调用。onMeasure在整个界面上需要放置一样东西或拿掉一样东西时会调用。比如addView就是放置,removeview就是拿掉,另外比较特殊的是,child设置为gone会触发onMeasure,但是invisible不会触发onMeasure。一旦执行过onMeasure,往往就会执行onLayout来重新布局
5. 分支影响整个分支直到root,比如上面的root有两个孩子,这两个孩子是不同的分支,这两个孩子是同级别,如果又孩子在点击button的时候让textview消失掉
01-19 17:40:56.185: I/cdd(15481):
MyLinearLayout--------onMeasure--480,676
01-19 17:40:56.185: I/cdd(15481):
ReSizeLayout--------onMeasure--480,741
01-19 17:40:56.185: I/cdd(15481):
MyLinearLayout--------onLayout--0,65,480,741
01-19 17:40:56.185: I/cdd(15481):
ReSizeLayout--------onLayout--0,0,480,741
它会影响右分支所有直到root,所以同一分支比较容易影响。但是我们看到没有影响到左孩子
为什么没有影响到做孩子呢,是因为没有影响到他的大小或者位置。
比如,在root下面加入一个孩子,如果孩子是加在前面两个孩子后面,那么对前面两个孩子都没有影响。但是如果加在两个孩子中间,那么对第二个孩子影响,影响的话就会执行onmeasure和onlayout
a.加在两个孩子后面
01-19 17:53:53.235: I/cdd(15939):
ReSizeLayout--------onMeasure--480,741
01-19 17:53:53.235: I/cdd(15939):
ReSizeLayout--------onLayout--0,0,480,741
b.加在两个孩子中间
01-19 17:45:55.345: I/cdd(15846):
MyTextView--------onMeasure--480,454
01-19 17:45:55.345: I/cdd(15846):
MyLinearLayout--------onMeasure--480,604
01-19 17:45:55.345: I/cdd(15846):
ReSizeLayout--------onMeasure--480,741
01-19 17:45:55.345: I/cdd(15846):
MyLinearLayout--------onSizeChanged--480,604,480,676
01-19 17:45:55.345: I/cdd(15846):
MyTextView--------onLayout--0,579,480,604
01-19 17:45:55.345: I/cdd(15846):
MyLinearLayout--------onLayout--0,137,480,741
01-19 17:45:55.345: I/cdd(15846):
ReSizeLayout--------onLayout--0,0,480,741
6. 一个分支下的影响很可能就是一条线到root,同级别的影响先决条件是,改变同级的大小或者位置,有时候没有改变大小或者位置,也可能调用