Cursor blinking

Android MeasureSpec 简介

Android 基础|Android|字数 465|阅读时长≈ 2 分钟

Android 的 MeasureSpec 是 View 测量过程中的核心机制,用于在布局阶段确定 View 的测量规则。它通过一个 32 位的整型值(int)将 尺寸(size) 和 模式(mode) 封装在一起,帮助父容器与子 View 协商最终的布局尺寸。


MeasureSpec 的结构

MeasureSpec 由 高 2 位表示测量模式,低 30 位表示具体尺寸

Code
// 测量规则【模式+尺寸】int mode = (measureSpec & MODE_MASK);   // 获取模式int size = (measureSpec & ~MODE_MASK);  // 获取尺寸

三种测量模式

模式说明典型场景
EXACTLY父容器已明确指定 View 的精确尺寸(如 match_parent 或具体数值),View 必须使用该尺寸。layout_width=100dp
AT_MOSTView 的尺寸不能超过父容器给定的最大值(如 wrap_content)。layout_width=wrap_content
UNSPECIFIED父容器未施加限制,View 可任意决定尺寸(通常用于系统内部或自定义布局)。ScrollView 测量子 View
UNSPECIFIED 补充说明
  • 含义: 父视图不对子视图施加任何限制,子视图可以根据自身需求自由调整大小(不是绝对的)。
  • 适用场景: 很少见,通常在某些特殊情况下才会出现。
  • 示例:
Code
    <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 LayoutParamsEXACTLY (固定数值)MATCH_PARENTWRAP_CONTENT
父容器:EXACTLYMode: EXACTLYSize: 固定值Mode: EXACTLYSize: 父尺寸Mode: AT_MOSTSize: 父尺寸
父容器:AT_MOSTMode: EXACTLYSize: 固定值Mode: AT_MOSTSize: 父尺寸Mode: AT_MOSTSize: 父尺寸
父容器:UNSPECIFIEDMode: EXACTLYSize: 固定值Mode: UNSPECIFIEDSize: 父尺寸Mode: AT_MOSTSize: 父尺寸

不同的父容器下子 View 测量规则不尽相同(FrameLayout、LinearLayout、ScrollView 等可以理解为 Android 官方的自定义 ViewGroup,这些容器存在即为了实现子 View 不同的排布,传递给子 View 的测量模式不完全一致),但大部分场景下遵循此表格,父容器 UNSPECIFIED 的模式很少出现,不用过度关注。

📌 总结:Android View 整体测量逻辑可以总结为一句话:向下传递约束,向上传递尺寸。