如果ScrollView嵌套ListView后渔呵,ListView只會顯示一個item的高度,如下圖:
圖1.png
原因是ScrollView在測量的時候改變了子view(即ListVIew)的測量模式厘肮,貼代碼:
//scrollview的onmeasure()方法
if (child.getMeasuredHeight() < desiredHeight) {
final int childWidthMeasureSpec = getChildMeasureSpec(
widthMeasureSpec, widthPadding, lp.width);
final int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
desiredHeight, MeasureSpec.EXACTLY);
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
}
整個測量過程也是一次根節(jié)點開始的遍歷過程,測量過程中父布局需要告訴子布局具體的模式和寬高值类茂,對子布局來說是一種約束,子布局需要在規(guī)定的范圍內(nèi)進行繪制巩检。
因此也就是scrollview改變了listview的測量模式和值(log得出Listview使用的是UNSPECIFIED模式),所以Listview最終只顯示一個item的高度兢哭。
解決方法:
重寫ListView的onmeasure()方法:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// int mode = MeasureSpec.getMode(heightMeasureSpec);
// switch (mode) {
// case MeasureSpec.UNSPECIFIED:
// Log.i("MyListVIew", "UNSPECIFIED");
// break;
// case MeasureSpec.EXACTLY:
// Log.i("MyListVIew", "EXACTLY");
// break;
// case MeasureSpec.AT_MOST:
// Log.i("MyListVIew", "AT_MOST");
// break;
// }
int i = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, i);
}
int i = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);這個代碼的含義:
設(shè)置一個指定的尺寸大小和指定模式的MeasureSpec值,第一個參數(shù)是設(shè)置指定的值冲秽,第二個參數(shù)是設(shè)定模式。
Integer.MAX_VALUE >> 2的含義:
MeasureSpec是一個int值矩父,int占4個字節(jié)锉桑,32位窍株,最高的兩位代表的是模式民轴,后面的30位值代表的是尺寸大小球订。因此Integer.MAX_VALUE >> 2就是最大的數(shù)值右移兩位(去掉代表模式的位)后裸,后面指定模式冒滩,剛好就組成了一個Measurespec值。
意思就是在父類最大的范圍內(nèi)去繪制Listview开睡。