🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
#### 4.2.1 MeasureSpec MeasureSpec代表一个32位int值,高2位代表SpecMode,低30位代表SpecSize, SpecMode是指测量模式,而SpecSize是指在某种测量模式下的规格大小。下面先看一下MeasureSpec内部的一些常量的定义,通过下面的代码,应该不难理解MeasureSpec的工作原理: private static final int MODE_SHIFT = 30; private static final int MODE_MASK = 0x3 << MODE_SHIFT; public static final int UNSPECIFIED = 0 << MODE_SHIFT; public static final int EXACTLY = 1 << MODE_SHIFT; public static final int AT_MOST = 2 << MODE_SHIFT; public static int makeMeasureSpec(int size, int mode) { if (sUseBrokenMakeMeasureSpec) { return size + mode; } else { return (size & ~MODE_MASK) | (mode & MODE_MASK); } } public static int getMode(int measureSpec) { return (measureSpec & MODE_MASK); } public static int getSize(int measureSpec) { return (measureSpec & ~MODE_MASK); } MeasureSpec通过将SpecMode和SpecSize打包成一个int值来避免过多的对象内存分配,为了方便操作,其提供了打包和解包方法。SpecMode和SpecSize也是一个int值,一组SpecMode和SpecSize可以打包为一个MeasureSpec,而一个MeasureSpec可以通过解包的形式来得出其原始的SpecMode和SpecSize,需要注意的是这里提到的MeasureSpec是指MeasureSpec所代表的int值,而并非MeasureSpec本身。 SpecMode有三类,每一类都表示特殊的含义,如下所示。 **UNSPECIFIED** 父容器不对View有任何限制,要多大给多大,这种情况一般用于系统内部,表示一种测量的状态。 **EXACTLY** 父容器已经检测出View所需要的精确大小,这个时候View的最终大小就是SpecSize所指定的值。它对应于LayoutParams中的match_parent和具体的数值这两种模式。 **AT_MOST** 父容器指定了一个可用大小即SpecSize, View的大小不能大于这个值,具体是什么值要看不同View的具体实现。它对应于LayoutParams中的wrap_content。