Android MeasureSpec 简介
Android 的 MeasureSpec 是 View 测量过程中的核心机制,用于在布局阶段确定 View 的测量规则。它通过一个 32 位的整型值(int)将 尺寸(size) 和 模式(mode) 封装在一起,帮助父容器与子 View 协商最终的布局尺寸。
MeasureSpec 的结构
MeasureSpec 由 高 2 位表示测量模式,低 30 位表示具体尺寸
// 测量规则【模式+尺寸】int mode = (measureSpec & MODE_MASK); // 获取模式int size = (measureSpec & ~MODE_MASK); // 获取尺寸三种测量模式
| 模式 | 说明 | 典型场景 |
|---|---|---|
| EXACTLY | 父容器已明确指定 View 的精确尺寸(如 match_parent 或具体数值),View 必须使用该尺寸。 | layout_width=100dp |
| AT_MOST | View 的尺寸不能超过父容器给定的最大值(如 wrap_content)。 | layout_width=wrap_content |
| UNSPECIFIED | 父容器未施加限制,View 可任意决定尺寸(通常用于系统内部或自定义布局)。 | ScrollView 测量子 View |
UNSPECIFIED 补充说明
- 含义: 父视图不对子视图施加任何限制,子视图可以根据自身需求自由调整大小(不是绝对的)。
- 适用场景: 很少见,通常在某些特殊情况下才会出现。
- 示例:
<ScrollView android:layout_width="match_parent" android:layout_height="wrap_content"> <-- 子 View 的高度模式 UNSPECIFIED--> <com.example.CustomView android:layout_width="match_parent" android:layout_height="wrap_content"/> </ScrollView>MeasureSpec 的生成
父容器根据自身的 MeasureSpec 和子 View 的 LayoutParams,生成子 View 的 MeasureSpec
| 父容器模式 \ 子 View LayoutParams | EXACTLY (固定数值) | MATCH_PARENT | WRAP_CONTENT |
|---|---|---|---|
| 父容器:EXACTLY | Mode: EXACTLYSize: 固定值 | Mode: EXACTLYSize: 父尺寸 | Mode: AT_MOSTSize: 父尺寸 |
| 父容器:AT_MOST | Mode: EXACTLYSize: 固定值 | Mode: AT_MOSTSize: 父尺寸 | Mode: AT_MOSTSize: 父尺寸 |
| 父容器:UNSPECIFIED | Mode: EXACTLYSize: 固定值 | Mode: UNSPECIFIEDSize: 父尺寸 | Mode: AT_MOSTSize: 父尺寸 |
不同的父容器下子 View 测量规则不尽相同(FrameLayout、LinearLayout、ScrollView 等可以理解为 Android 官方的自定义 ViewGroup,这些容器存在即为了实现子 View 不同的排布,传递给子 View 的测量模式不完全一致),但大部分场景下遵循此表格,父容器 UNSPECIFIED 的模式很少出现,不用过度关注。
📌 总结:Android View 整体测量逻辑可以总结为一句话:向下传递约束,向上传递尺寸。