在新版本中需求變更導緻布局需要變化,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>
- import android.content.Context;
- import android.support.v7.widget.LinearLayoutManager;
- import android.support.v7.widget.RecyclerView;
- import android.util.Log;
- import android.view.View;
- import android.view.ViewGroup;
- public class FullyLinearLayoutManager extends LinearLayoutManager {
- private static final String TAG = FullyLinearLayoutManager.class.getSimpleName();
- public FullyLinearLayoutManager(Context context) {
- super(context);
- }
- public FullyLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
- super(context, orientation, reverseLayout);
- }
- private int[] mMeasuredDimension = new int[2];
- @Override
- public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state,
- int widthSpec, int heightSpec) {
- final int widthMode = View.MeasureSpec.getMode(widthSpec);
- final int heightMode = View.MeasureSpec.getMode(heightSpec);
- final int widthSize = View.MeasureSpec.getSize(widthSpec);
- final int heightSize = View.MeasureSpec.getSize(heightSpec);
- Log.i(TAG, "onMeasure called. \nwidthMode " + widthMode
- + " \nheightMode " + heightSpec
- + " \nwidthSize " + widthSize
- + " \nheightSize " + heightSize
- + " \ngetItemCount() " + getItemCount());
- int width = 0;
- int height = 0;
- for (int i = 0; i < getItemCount(); i++) {
- measureScrapChild(recycler, i,
- View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
- View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
- mMeasuredDimension);
- if (getOrientation() == HORIZONTAL) {
- width = width + mMeasuredDimension[0];
- if (i == 0) {
- height = mMeasuredDimension[1];
- }
- } else {
- height = height + mMeasuredDimension[1];
- if (i == 0) {
- width = mMeasuredDimension[0];
- }
- }
- }
- switch (widthMode) {
- case View.MeasureSpec.EXACTLY:
- width = widthSize;
- case View.MeasureSpec.AT_MOST:
- case View.MeasureSpec.UNSPECIFIED:
- }
- switch (heightMode) {
- case View.MeasureSpec.EXACTLY:
- height = heightSize;
- case View.MeasureSpec.AT_MOST:
- case View.MeasureSpec.UNSPECIFIED:
- }
- setMeasuredDimension(width, height);
- }
- private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec,
- int heightSpec, int[] measuredDimension) {
- try {
- View view = recycler.getViewForPosition(0);//fix 動态添加時報IndexOutOfBoundsException
- if (view != null) {
- RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams();
- int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec,
- getPaddingLeft() + getPaddingRight(), p.width);
- int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec,
- getPaddingTop() + getPaddingBottom(), p.height);
- view.measure(childWidthSpec, childHeightSpec);
- measuredDimension[0] = view.getMeasuredWidth() + p.leftMargin + p.rightMargin;
- measuredDimension[1] = view.getMeasuredHeight() + p.bottomMargin + p.topMargin;
- recycler.recycleView(view);
- }
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- }
- }
- }
然後在代碼裡添加如下:
[html] view plain copy - FullyLinearLayoutManager linearLayoutManager = new FullyLinearLayoutManager(this);
- recyclerView.setNestedScrollingEnabled(false);
- //設定布局管理器
- recyclerView.setLayoutManager(linearLayoutManager);