项目中看见一行代码很有趣,自定义了一个gridview。这个自定义中 重写了 onmeasure方法:
public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); }
没见过啊 然后我就研究一下 发现蛮有趣的。
这串代码的背景::可能经常遇到嵌套ListView、ScrollView的问题,百度一搜,都是现成的代码,而且都是一样的,就是重写onMeasure方法
首先 在 Android里面,用32位的int值来表示一个控件的模式与大小。
模式用最高两位表示:
private static final int MODE_SHIFT = 30;
- public static final int UNSPECIFIED = 0 << MODE_SHIFT;
- public static final int EXACTLY = 1 << MODE_SHIFT;(相当于match——parent)
- public static final int AT_MOST = 2 << MODE_SHIFT;(相当于wrap——content)
不确定模式是0左移30位,也就是int类型的最高两位是00
精确模式是1左移30位,也就是int类型的最高两位是01
最大模式是是2左移30位,也就是int类型的最高两位是10kop
低位30位表示大小。
所以Integer.MAX_VALUE >> 2就是将 Integer.MAX_VALUE这个32位的值右移两位 。就保留下了 大小 也就是size值。
MeasureSpec.AT_MOST 这个模式值就相当于 给出了 模式值 这个 32位数的前两位。
以此,MeasureSpec的makeMeasureSpec的方法根据输入的大小值 与模式值来生成一个32位t值,这个int值封装了模式和大小信息
再通过 MeasureSpec的两个组装方法:
public static int getMode(int measureSpec),这个方法的作用是通过一个int值来获取里面的模式信息
public static int getSize(int measureSpec),这个方法的作用是通过一个int值来获取里面的大小信息
最后super.onMeasure(widthMeasureSpec, expandSpec);实现onmeasure全部功能。
最后根据这个例子讲一下怎么理解这一串代码:
给出了控件最大极限的size(实际不可能这么大),与 atmost模式 就是说 根据32位值 计算调整 将结果的大小值传递给父控件。
super.onMeasure(widthMeasureSpec, expandSpec);说明 调整的只是 高度 宽度不改变。