Android布局measure,android  OnMeasure()深入理解(总结)

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,同级别的影响先决条件是,改变同级的大小或者位置,有时候没有改变大小或者位置,也可能调用

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值