Skip to content
阅读进度

MeasureSpec 三种模式是什么?wrap_content 怎么变成具体尺寸? ​

返回 View 与显示链路 目录

标准回答 ​

MeasureSpec 包含尺寸与模式。EXACTLY 表示父容器给定准确尺寸;AT_MOST 表示最多这么大,View 在上限内选择;UNSPECIFIED 表示本次测量在这个方向没有给出限制。

父容器综合自己的测量约束、可用空间、padding、margin 和孩子的 LayoutParams,生成孩子的 MeasureSpec。孩子再依据内容、最小尺寸和约束,得到 measuredWidth 与 measuredHeight。

因此 wrap_content 不是一种 MeasureSpec 模式,而是孩子表达的布局需求。比如内容理想宽度为 180px,父容器给 AT_MOST 120px,孩子应在约束内选择尺寸;后续文字是否换行、省略或裁剪,还取决于控件实现。match_parent 也不能脱离父容器当次测量条件,机械等同于永远 EXACTLY。

关键机制 ​

  • 测量结果包含控件自身的 padding;margin 通常由父容器在为孩子计算可用空间时处理。
  • 自定义 View 的 onMeasure 需要给出结果,可借助 resolveSize / resolveSizeAndState 处理约束。
  • 父容器可能对孩子测量多次;不能假设每轮遍历中 onMeasure 永远只执行一次。

通俗例子 ​

自定义圆形控件希望内容为 80dp,加上左右 padding 后得到期望宽度,再用父容器约束裁定实际测量值。画圆时仍需适应最终内容区。

追问与回答 ​

EXACTLY 下内容比给定尺寸大怎么办? ​

View 仍应遵守父容器指定的尺寸。内容如何适配由控件决定,例如 TextView 可以换行、省略或被裁剪。不能因为内容很长,就无视 EXACTLY 自行把测量宽度扩大。

易混淆点 ​

AT_MOST 的 size 是上限,不是必须占满;UNSPECIFIED 也不是让控件返回无限大。

参考资料 ​

内容来源 ​

用完整回答理解机制,用真实证据解释项目。