天天看點

關于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);  

繼續閱讀