听说你想玩RecyclerView嵌套GridView  

效果图

 
听说你想玩RecyclerView嵌套GridView
 
RecyclerView嵌套GridView

问题及原因

有很多小伙伴们可能会遇到这样的问题:
为什么不论我传入多大size的List,我的GridView只能显示一行?

因为RecyclerView和GridView都属于可滑动控件,两者嵌套会导致滑动冲突,Android不允许这样的情况出现,所以索性将GridView宽度定死,定为一行Item的高度且不可滑动,所以导致了我们只显示一行这个问题的出现。

源码浅析

解决的思路是:重新计算高度!

想要计算高度,我们就要知道它计算高度的机制。我们来看看源码:

 
听说你想玩RecyclerView嵌套GridView
 
继承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())