view工作原理-计算视图大小的过程(onMeasure)

view的视图有两种情况:


  • 内容型视图:由视图的内容决定其大小。
  • 图形型视图:父视图为view动态调整大小。
    ### measure的本质

把视图布局使用的“相对值”转化成具体值的过程,即把WRAP_CONTENT,MATCH_PARENT转化为具体的值。

measure内部的设计思路

这里写图片描述
再来看一下View中measure()函数原型:

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

当父视图对子视图进行measure操作时,会调用子视图的measure()方法。该函数的意思是父视图为子视图所提供的measure的”规格”,因为父视图最终为子视图提供的”窗口”大小是由父视图和子视图共同决定的。该值有32位组成,高16位保存的是specMode, 低16位保存spcMode。
spceMode有三种:

  • MeasureSpec.EXACTLY: “确定的”, 父视图希望子视图的大小应该是spec中指定的。在一般情况下, View的设计者应该遵守指示,将View的measureHeight和measuredWidth设置成指定的值。
  • MeasureSpec.AT_MOST:”最多”,子视图最多是specSize中指定的值。
  • MeasureSpec.UNSPECIFIED: “没有限制”, 此时View的设计者可以根据自身的特性设置视图的大小。
    以上介绍measureSpec的语义,该参数是父视图传递给子视图的,看一下measureSpec是如何产生的:

ViewRoot中,调用host.measure()函数,参数分别是局部变量childWidthMeasureSpec和childHeightMeasureSpec,这两个变量的赋值最初是通过调用getRootMeasureSpec()函数获得的:

childWidthMeasureSpec = getRootMeasureSpec(desiredWindowWidth, lp.width);
childHeightMeasureSpec = getRootMeasureSpec(desiredWindowWidth, lp.height);

ViewGroup中的measureChildWidthMargins()

  1. 调用child.getLayoutParams()获得子视图的LayoutParams属性。
  2. 调用两次getChildMeasureSpec()函数,分别计算出该子视图的宽度和高度的spec。
  3. 调用child.measure()函数。子视图可以重载onMeasure()函数,并调用setMeasureDimension()函数设置任意大小的布局,这将成为子视图的最终布局大小。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值