普通的做法是设置一个高度,然后里面能显示出来几行就是几行,如果里面的内容高度变了,就需要重新调整高度来适配。
观察了一下它的onMeasure
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { ..... if (heightMode == MeasureSpec.AT_MOST) { int ourSize = mListPadding.top + mListPadding.bottom; final int numColumns = mNumColumns; for (int i = 0; i < count; i += numColumns) { ourSize += childHeight; if (i + numColumns < count) { ourSize += mVerticalSpacing; } if (ourSize >= heightSize) { ourSize = heightSize; break; } } heightSize = ourSize; } ... }
发现,如果是它设置wrap_content,可以通过改变它的adapter来确定行数,具体方法如下是:
MyAdapter
@Override public int getCount() { if (mIsOnMeasure && super.getCount() >MAX_COUNT) { return MAX_COUNT; } return super.getCount(); } public void setOnMeasureStatus(boolean isOnMeasure) { mIsOnMeasure = isOnMeasure; } Gridview- > @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { int heightMode = MeasureSpec.getMode(heightMeasureSpec); if (heightMode == MeasureSpec.AT_MOST) { ((MyAdapter) getAdapter()).setOnMeasureStatus(true); super.onMeasure(widthMeasureSpec, heightMeasureSpec); int height = getMeasuredHeight(); ((FolderAdapter) getAdapter()).setOnMeasureStatus(false); super.onMeasure(widthMeasureSpec, heightMeasureSpec); setMeasuredDimension(getMeasuredWidthAndState(), MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)); } else { super.onMeasure(widthMeasureSpec, heightMeasureSpec); } }
在onMeasure的时候,先让adapter假装有行数×列数的内容,调用 super.onMeasure先算出一个高,这个就是期望高度。
然后在调用一次 super.onMeasure(widthMeasureSpec, heightMeasureSpec),把整个view绘制出来
最后通过setMeasuredDimension就可以做到了。