View.onMeasure()

问题:Android是如何确定View大小的?


width和height是独立的,可以分开考虑,所以我们只关注width;

假设:

1)我们先自定义三个View A,B,C,全部继承自LinearLayout;

2)我们的测试机的屏幕宽度是1080;


实验1, 如果全部跟着父控件走:


   

       

   


则执行顺序是:

A EXACTLY 1080 (A的上级是1080宽度,而A的愿望是match_parent, 所以上级给A的spec就是EXACTLY 1080)

B EXACTLY 1080 (A的spec是EXACTLY 1080, B自己的愿望是match_parent,所以A给B的spec就是EXACTLY 1080)

C EXACTLY 1080 (B的spec是EXACTLY 1080, 而C自己的愿望是match_parent, 所以B给C的spec就是EXACTLY 1080)

C.width = 1080 (C的spec是EXACTLY 1080,  于是宽度就确定为1080)

B.width = 1080 (C的spec是EXACTLY 1080,  于是宽度就确定为1080)

A.width = 1080(C的spec是EXACTLY 1080,  于是宽度就确定为1080)

spec从上往下传递,而最终size的确定顺序是从下往上的;


实验2,如果全部跟着子控件走:

   

       

   


则执行顺序是:

A AT_MOST 1080(A的上级是1080的,而A想包含内容,所以上级就规定A最多1080宽)

B AT_MOST 1080 (A最多1080,而B想包含内容,所以A规定B最多1080宽)

C AT_MOST 1080 (B最多1080,而C想包含内容,所以B规定C最多1080宽)

C.width = 0 (C的spec是AT_MOST 1080, 而C作为LinearLayout的子类,由于没有内容,所以决定取0,其实这儿C只要不超过1080,可以随便取值的)

B.width = 0 (B的spec是AT_MOST 1080, 而C已经确定为0,为了wrap C,B可以取0到1080之间的任意值,这儿实际取值0,注意B既考虑了第一遍从上而下传过来的spec,也考虑了child的宽度)

A.width = 0 (A的spec是AT_MOST 1080, 而B已经确定为0,为了wrap B,A可以取0到1080之间的任意值,这儿实际取值0)


实验3,parent让child定,child让parent定,简单点,2级就能说明问题:

   

你可能感兴趣的:(View.onMeasure())