接着上面一篇文章。
當GridView不知道parent高度的時候,也就是MeasureSpec是UNSPECIFIED,這個時候,GridView高度為第一個child的高度,並顯示滾動條。
1 mItemCount = mAdapter == null ? 0 : mAdapter.getCount(); 2 final int count = mItemCount; 3 if (count > 0) { 4 final View child = obtainView(0, mIsScrap); 5 6 AbsListView.LayoutParams p = (AbsListView.LayoutParams) child.getLayoutParams(); 7 if (p == null) { 8 p = (AbsListView.LayoutParams) generateDefaultLayoutParams(); 9 child.setLayoutParams(p); 10 } 11 p.viewType = mAdapter.getItemViewType(0); 12 p.forceAdd = true; 13 14 int childHeightSpec = getChildMeasureSpec( 15 MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), 0, p.height); 16 int childWidthSpec = getChildMeasureSpec( 17 MeasureSpec.makeMeasureSpec(mColumnWidth, MeasureSpec.EXACTLY), 0, p.width); 18 child.measure(childWidthSpec, childHeightSpec); 19 20 childHeight = child.getMeasuredHeight(); 21 childState = combineMeasuredStates(childState, child.getMeasuredState()); 22 23 if (mRecycler.shouldRecycleViewType(p.viewType)) { 24 mRecycler.addScrapView(child, -1); 25 } 26 } 27 28 if (heightMode == MeasureSpec.UNSPECIFIED) { 29 heightSize = mListPadding.top + mListPadding.bottom + childHeight + 30 getVerticalFadingEdgeLength() * 2; 31 } 32 33 if (heightMode == MeasureSpec.AT_MOST) { 34 int ourSize = mListPadding.top + mListPadding.bottom; 35 36 final int numColumns = mNumColumns; 37 for (int i = 0; i < count; i += numColumns) { 38 ourSize += childHeight; 39 if (i + numColumns < count) { 40 ourSize += mVerticalSpacing; 41 } 42 if (ourSize >= heightSize) { 43 ourSize = heightSize; 44 break; 45 } 46 } 47 heightSize = ourSize; 48 }
我們可以發現,確實是只設置為第一個child的高度,當MeasureSpec是AT_MOST的時候,才會讀取所有child的高度。
再網上,搜到了下面的辦法。
1 heightMeasureSpec = MeasureSpec.makeMeasureSpec(Integer.MAX_VALUE, MeasureSpec.AT_MOST);
其實這是不對的,MeasureSpec的前兩個bits是mode,size的大小不能超過30位。於是,稍微修改,size設置為1000000,應該是足夠了,當不足夠的時候,你的app如果還沒更新早就該被淘汰了。
1 heightMeasureSpec = MeasureSpec.makeMeasureSpec(1000000, MeasureSpec.AT_MOST);