源码说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public class View implements ... {
...
public static class MeasureSpec {
//Android属于32位Linux操作系统,int类型占32位。
//使用一个int表示MeasureSpec,高2位表示Mode,低30位表示真实值

private static final int MODE_SHIFT = 30;
//取MODE的掩码值
private static final int MODE_MASK = 0x3 << MODE_SHIFT;
//高两位使用00表示UNSPECIFIED
public static final int UNSPECIFIED = 0 << MODE_SHIFT;
//高两位使用01表示EXACTLY
public static final int EXACTLY = 1 << MODE_SHIFT;
//高两位使用10表示AT_MOST
public static final int AT_MOST = 2 << MODE_SHIFT;

//size与mode直接相加得出MeasureSpec
public static int makeMeasureSpec(int size, int mode) {
return size + mode;
}
//使用掩码获取mode
public static int getMode(int measureSpec) {
return (measureSpec & MODE_MASK);
}
//使用掩码获取size
public static int getSize(int measureSpec) {
return (measureSpec & ~MODE_MASK);
}
}

解析

MeasureSpec类封装了父View传递给子View的布局(layout)要求。每个MeasureSpec实例代表宽度或者高度。

对应源码,有三种MODE:

  • UNSPECIFIED

    父视图不对子视图有任何约束,它可以达到所期望的任意尺寸。比如 ListView、ScrollView,一般自定义 View 中用不到。

  • EXACTLY

    父元素决定自元素的确切大小,子元素将被限定在给定的边界里而忽略它本身大小,对应的属性为match_parent或具体值。

  • AT_MOST

    子元素至多达到指定大小的值,即父视图指定一个最大尺寸,对应属性为wrap_content。