在項目開發中,可能經常遇到嵌套ListView、ScrollView的問題,就是重寫onMeasure方法.解決如下
public class ExpandListView extends ListView { public ExpandListView(Context context) { super(context); } public ExpandListView(Context context, AttributeSet attrs) { super(context, attrs); } public ExpandListView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @TargetApi(Build.VERSION_CODES.LOLLIPOP) public ExpandListView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2 , MeasureSpec.AT_MOST); super.onMeasure(widthMeasureSpec, expandSpec); } }
MeasureSpec這個類,如下
3種模式
- UNSPECIFIED模式,官方意思是:父布局沒有給子布局強加任何約束,子布局想要多大就要多大,說白了就是不確定大小
- EXACTLY模式,官方意思是:父布局給子布局限定了准確的大小,子布局的大小就是精確的,父親給多大就是多大
- AT_MOST模式,官方意思是:父布局給定了一個最大的值,子布局的大小不能超過這個值,當然可以比這個值小
3個方法
public static int makeMeasureSpec(int size, int mode) ,這個方法的作用是根據大小和模式來生成一個int值,這個int值封裝了模式和大小信息 public static int getMode(int measureSpec),這個方法的作用是通過一個int值來獲取里面的模式信息 public static int getSize(int measureSpec),這個方法的作用是通過一個int值來獲取里面的大小信息
調用了makeMeasureSpec方法,這個方法是用來生成一個帶有模式和大小信息的int值的,
第一個參數Integer.MAX_VALUE >> 2,這個參數是傳的一個大小值要生成的控件,它的大小最大值是int的最低30位的最大值,先取Integer.MAX_VALUE來獲取int值的最大值,然后左移2位就得到這個臨界值最大值
當然,我們在手機上的控件的大小不可能那么大,極限值就那么大,實際肯定比那個小,所以這個模式就得選擇MeasureSpec.AT_MOST,最后將生成的這個大小傳遞給父控件就可以了,super.onMeasure(widthMeasureSpec, expandSpec),這個函數只改變的是控件的高度,寬度沒有改變,實際開發當中不管listview有多少條數據,都能一次性展現出來