听说你想玩RecyclerView嵌套GridView
效果图
RecyclerView嵌套GridView
问题及原因
有很多小伙伴们可能会遇到这样的问题:
为什么不论我传入多大size的List,我的GridView只能显示一行?
因为RecyclerView和GridView都属于可滑动控件,两者嵌套会导致滑动冲突,Android不允许这样的情况出现,所以索性将GridView宽度定死,定为一行Item的高度且不可滑动,所以导致了我们只显示一行这个问题的出现。
源码浅析
解决的思路是:重新计算高度!
想要计算高度,我们就要知道它计算高度的机制。我们来看看源码:
继承GridView自定义控件里的onMeasure方法
我们可以看到如果我们自定义控件,且什么都不做时,它会调用父类(GridView)的onMeasure方法,我们来看看GridView里面的onMeasure源码:
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// Sets up mListPadding
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
if (widthMode == MeasureSpec.UNSPECIFIED) {
if (mColumnWidth > 0) {
widthSize = mColumnWidth + mListPadding.left + mListPadding.right;
} else {
widthSize = mListPadding.left + mListPadding.right;
}
widthSize += getVerticalScrollbarWidth();
}
int childWidth = widthSize - mListPadding.left - mListPadding.right;
boolean didNotInitiallyFit = determineColumns(childWidth);
int childHeight = 0;
int childState = 0;
mItemCount = mAdapter == null ? 0 : mAdapter.getCount();
final int count = mItemCount;
if (count > 0) {
final View child = obtainView(0, mIsScrap);
AbsListView.LayoutParams p = (AbsListView.LayoutParams) child.getLayoutParams();
if (p == null) {
p = (AbsListView.LayoutParams) generateDefaultLayoutParams();
child.setLayoutParams(p);
}
p.viewType = mAdapter.getItemViewType(0);
p.forceAdd = true;
int childHeightSpec = getChildMeasureSpec(
MeasureSpec.makeSafeMeasureSpec(MeasureSpec.getSize(heightMeasureSpec),
MeasureSpec.UNSPECIFIED), 0, p.height);
int childWidthSpec = getChildMeasureSpec(
MeasureSpec.makeMeasureSpec(mColumnWidth, MeasureSpec.EXACTLY), 0, p.width);
child.measure(childWidthSpec, childHeightSpec);
childHeight = child.getMeasuredHeight();
childState = combineMeasuredStates(childState, child.getMeasuredState())