ScrollView鑲嵌listview顯示不全的原因,scrollviewlistview
當ScrollView鑲嵌listview會顯示不全,通過查看ScrollView測量高度的源碼,會發現ScrollView重寫了父類viewGroup的measureChildWithMargins方法:
測量child的高度,傳遞的是UNSPECIFIED(儘可能大的)
再來看看listview自身onMeasure的測量高度方法:
final int heightMode = MeasureSpec.getMode(heightMeasureSpec),heightMeasureSpec是父容器傳過來的;
當測量方式為UNSPECIFIED時,高度=top+bottom+一個childHeight+兩個邊框長度。
就會出現listview顯示不全。
解決方案:
自訂一個listview,重寫listview的onMeasure方法:
看看makeMeasureSpec方法
將測量方式改為AT_MOST,那為什麼我們又要給個最大值呢,跟著方法走:
會發現listview在測量child時有個這個方法,設最大值是為了跳過這個方法,我們只需要測量child高度累加就行了。
那為啥又要位移兩位呢?下面代表個人看法:
listview擷取高度是這樣算的:
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
heightMeasureSpec是
int expandSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE >> 2, MeasureSpec.AT_MOST);
super.onMeasure(widthMeasureSpec, expandSpec);
傳過來的。makeMeasureSpec方法 return (size & ~MODE_MASK) | (mode & MODE_MASK)拼接的,我們再看看AT_MOST:
public static final int AT_MOST = 2 << MODE_SHIFT;
所有個人認為右移兩位使heightSize剛好為Integer.MAX_VALUE。