前言
該問題是一個經常會碰到的問題,之前是隻用在一個佈局文件中,所以寫死固定高度湊合也能用,但是當使用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方法,使其不會出現滾動條的同時,獲得充分的高度。
說明(引用MeasureSpec中三種模式)
假如此處採用
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的代碼覆蓋)