View树遍历的情况-- ② measure的内部设计思路

View系统启动measure是从ViewRoot中调用host.measure()开始, 过程如图 :  [书本:P299]


host一般情况下是ViewGroup的实例,会在onMeasure()中对所包含的子视图逐一进行measure(),为了简化程序官方提供了一个 measureChildWithMargins()来自动对子视图进行measure(),如果子视图是个ViewGroup则会再次进行一次递归.


View的measure函数的原形是:

public final void measure(int widthMeasureSpec , int heightMeasureSpec);

SpecMode分三种:

①:MeasureSpec.EXACTLY : "确定的"  , 意思是:父视图希望子视图的大小应该是specSize中指定.

②:MeasureSpec.AT_MOST: "最多" ,意思是 : 子视图的大小最多是specSize中指定的值.

③:MeasureSpec.UNSPECIFIED : "没有限制" 意思是 : 此时View设计者可以根据自身的特性设定大小


上面的MeasureSpec是由父视图传递给子视图的,那么最根部的MeasureSpec是怎么产生的呢?

就是在ViewRoot 的 host.measure() 函数时,获取到的屏幕宽高进行的设定.

假设根布局也制定了特定的宽高,host.measure()还是根据Spec来获取屏幕宽高进行设定.因为布局最后的宽高是由父布局和字布局共同决定的,而不是单方面决定的.



---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

ViewGroup中的measureChildMargins()

1:measureChildren() : 该函数内部使用for()调用measureChild()对每一个子视图进行measure()

2:measureChild() : 为指定的子视图进行measure()

3:measureChildWithMargins() : 该函数与measureChild的唯一区别在于,measure时考虑把margin和padding 也作为子视图大小的一部分 .

创建View一般分两种

①XML定义 然后布局填充

②代码生成 然后Add

对于第一种实际上是内部进行了②的操作,当通过getSystemService()获取到inflater对象的时候第一个参数指定布局文件  第二个参数指定该View的父视图(一般为空)

而在XML中则使用具体标签来表示一个View,比如LinearLayout标签表示一个LinearLayout对象.

<以 measureChildWithMargins() 为例讲解>

而在inflate()内部会根据这些标签来进行②的操作动态生成视图对象,创建好后,此时对象内部的LayoutParams属性是空的.所有的View对象想要被显示到屏幕上,必须先调用addView()方法把View添加到当前窗口的View树中.


在该段代码中,由于Child当前的LayoutParams是空的所以会走 1825行 来生成一个LayoutParams对象.所有的ViewGroup基本都会重载该对象.比如LinearLayout就重载了并返回了一个LinearLayout.LayoutParams对象


PS:如果你自己写一个ViewGroup而不重载geneareDeafaultLayouParams()

那么程序在向你定义的这个ViewGroup中添加View的时候,将使用ViewGroup中默认的ViewGroup.LayoutParams,这将导致在XML中定义的margin属性无效.

且不能在自定义的ViewGroup中使用measureChildWithMargin(),而只能使用mesureChild() 否则会因为强制类型转换错误而发生异常


---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

LinearLayout中的onMeasure()过程举例:

( View系统中的measure()必须由相应的ViewGroup实例共同参与才能完成一个真正的measure() )


下一节:权重的先后显示问题















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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值