该问题是一个经常会碰到的问题,之前是只用在一个布局文件中,所以写死固定高度凑合也能用,但是当使用ScrollView内嵌ListView写成一个自定义控件无法判断高度时这种方法就不适用了。下面介绍一个很简单的方法一次性替换,永久无忧~
public class NoScrollListView extends ListView{
public NoScrollListView(Context context){
super(context);
}
public NoScrollListView(Context context, AttributeSet attrs, int defStyle){
super(context,attrs,defStyle);
}
public NoScrollListView(Context context, AttributeSet attrs){
super(context,attrs);
}
public void onMeasure(int widthMeasureSpec,int heightMeasureSpec){
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE>>2,MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
}
}
该自定义控件只是重写了listview控件的onMeasure方法,使其不会出现滚动条的同时,获得充分的高度。
假如此处采用
int expandSpec = MeasureSpec.makeMeasureSpec(1000>>2,MeasureSpec.AT_MOST);
1000的二进制:1111101000
右移2位后:11111010,十进制为:250
这样就指定了listview的高度为250px以内的最大允许值(一般就是250)
把AT_MOST改为EXACTLY,则精确指定listview高度值为250px,如果listview内容全部显示的高度为500px(大于250px),那么当measureSpec中size的值为250px(小于500px)时,效果是一样的
如果设置的measureSpec中size的值大于listview内容全部显示的高度,那么设置成AT_MOST时,最多显示listview内容全部显示的高度,而EXACTLY还是显示measureSpec中size的值,所以EXACTLY在这种情况下,后面会留有空白高度(measureSpec中size的值大于listview内容全部显示的高度的部分显示为空白)
所以,一般这样写可以让listview正确测量:
int width = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE>>2,MeasureSpec.AT_MOST);
MAX_VALUE右移2位后,即使不是最大整数了,listview的高度也一般不可能超过它。
第一个参数有个最大值的限制:1073741823(二进制的30个1),MAX_VALUE是1个0加上31个1(二进制),所以也可以右移1位,但是由于最前面两位表示mode,而不是size,所有右移1位和右移2位是一样的(前面两位的值都会被mode的代码覆盖)