天天看点

关于ScrollView嵌套RecyclerView时RecyclerView不显示的问题

在新版本中需求变更导致布局需要变化,RecyclerView外需要一层ScrollView来处理滑动。发布前夕发现在API 23 & 24上RecyclerView显示不完整。


  
  光速冷静下来,马上去stackoverflow翻了一下,有人说ScrollView加上          android:fillViewport="true"                 ,但是我加上并没有解决问题。后来在RecyclerView外面加了一层RelativeLayout,问题解决。如果你在API 23 & 24上也遇到这个问题,可以参考一下。


         
<android.support.v4.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        >

        <!-- DEV NOTE: Outer wrapper relative layout is added intentionally to address issue
                 that only happens on Marshmallow & Nougat devices (API 23 & 24).
                 On marshmallow API 23, the "RecyclerView" `layout_height="wrap_content"` does NOT
                 occupy the height of all the elements added to it via adapter. The result is cut out
                 items that is outside of device viewport when it loads initially.
                 Wrapping "RecyclerView" with "RelativeLayout" fixes the issue on Marshmallow devices.
            -->

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <com.jcodecraeer.xrecyclerview.XRecyclerView
                android:id="@+id/rv_fragment_find_tips_list"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" 
                />
        </RelativeLayout>


    </android.support.v4.widget.NestedScrollView>
           
  1. import android.content.Context;  
  2. import android.support.v7.widget.LinearLayoutManager;  
  3. import android.support.v7.widget.RecyclerView;  
  4. import android.util.Log;  
  5. import android.view.View;  
  6. import android.view.ViewGroup;  
  7. public class FullyLinearLayoutManager extends LinearLayoutManager {  
  8.     private static final String TAG = FullyLinearLayoutManager.class.getSimpleName();  
  9.     public FullyLinearLayoutManager(Context context) {  
  10.         super(context);  
  11.     }  
  12.     public FullyLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {  
  13.         super(context, orientation, reverseLayout);  
  14.     }  
  15.     private int[] mMeasuredDimension = new int[2];  
  16.     @Override  
  17.     public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state,  
  18.                           int widthSpec, int heightSpec) {  
  19.         final int widthMode = View.MeasureSpec.getMode(widthSpec);  
  20.         final int heightMode = View.MeasureSpec.getMode(heightSpec);  
  21.         final int widthSize = View.MeasureSpec.getSize(widthSpec);  
  22.         final int heightSize = View.MeasureSpec.getSize(heightSpec);  
  23.         Log.i(TAG, "onMeasure called. \nwidthMode " + widthMode  
  24.                 + " \nheightMode " + heightSpec  
  25.                 + " \nwidthSize " + widthSize  
  26.                 + " \nheightSize " + heightSize  
  27.                 + " \ngetItemCount() " + getItemCount());  
  28.         int width = 0;  
  29.         int height = 0;  
  30.         for (int i = 0; i < getItemCount(); i++) {  
  31.             measureScrapChild(recycler, i,  
  32.                     View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),  
  33.                     View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),  
  34.                     mMeasuredDimension);  
  35.             if (getOrientation() == HORIZONTAL) {  
  36.                 width = width + mMeasuredDimension[0];  
  37.                 if (i == 0) {  
  38.                     height = mMeasuredDimension[1];  
  39.                 }  
  40.             } else {  
  41.                 height = height + mMeasuredDimension[1];  
  42.                 if (i == 0) {  
  43.                     width = mMeasuredDimension[0];  
  44.                 }  
  45.             }  
  46.         }  
  47.         switch (widthMode) {  
  48.             case View.MeasureSpec.EXACTLY:  
  49.                 width = widthSize;  
  50.             case View.MeasureSpec.AT_MOST:  
  51.             case View.MeasureSpec.UNSPECIFIED:  
  52.         }  
  53.         switch (heightMode) {  
  54.             case View.MeasureSpec.EXACTLY:  
  55.                 height = heightSize;  
  56.             case View.MeasureSpec.AT_MOST:  
  57.             case View.MeasureSpec.UNSPECIFIED:  
  58.         }  
  59.         setMeasuredDimension(width, height);  
  60.     }  
  61.     private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec,  
  62.                                    int heightSpec, int[] measuredDimension) {  
  63.         try {  
  64.             View view = recycler.getViewForPosition(0);//fix 动态添加时报IndexOutOfBoundsException  
  65.             if (view != null) {  
  66.                 RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams();  
  67.                 int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec,  
  68.                         getPaddingLeft() + getPaddingRight(), p.width);  
  69.                 int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec,  
  70.                         getPaddingTop() + getPaddingBottom(), p.height);  
  71.                 view.measure(childWidthSpec, childHeightSpec);  
  72.                 measuredDimension[0] = view.getMeasuredWidth() + p.leftMargin + p.rightMargin;  
  73.                 measuredDimension[1] = view.getMeasuredHeight() + p.bottomMargin + p.topMargin;  
  74.                 recycler.recycleView(view);  
  75.             }  
  76.         } catch (Exception e) {  
  77.             e.printStackTrace();  
  78.         } finally {  
  79.         }  
  80.     }  
  81. }  
然后在代码里添加如下: [html]  view plain  copy
  1. FullyLinearLayoutManager linearLayoutManager = new FullyLinearLayoutManager(this);  
  2.         recyclerView.setNestedScrollingEnabled(false);  
  3.         //设置布局管理器  
  4.         recyclerView.setLayoutManager(linearLayoutManager);  

继续阅读