Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set Height of Inner RecyclerView wrap_content

I have a recyclerview inside another recyclerview. I want to make height of inner recyclerview "warp_content".

I came to know it is possible with new version of recyclerview which is mentioned below.

'com.android.support:recyclerview-v7:23.2.0'

But the problem is, by setting height = wrap_content I can see only first item.

Any Help will be great.

like image 790
user2566484 Avatar asked Dec 25 '22 08:12

user2566484


2 Answers

Because I am using a RecyclerView this does not work see:

https://code.google.com/p/android/issues/detail?id=74772

and

Nested Recycler view height doesn't wrap it's content

On both of these pages people suggest to extend LinearLayoutManager and to override onMeasure()

RecyclerView doesn't have the wrap_content by default. You have to use the RecyclerView with wrap_content Layout Manager such as, WrapLinearLayoutManager e.g CustomLinearLayoutManager .

CustomLinearLayoutManager.java

    public class CustomLinearLayoutManager extends LinearLayoutManager {

private static final String TAG = CustomLinearLayoutManager.class.getSimpleName();

public CustomLinearLayoutManager(Context context) {
    super(context);
}

public CustomLinearLayoutManager(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);

    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();
    } 
}

}

like image 171
Maheshwar Ligade Avatar answered Jan 07 '23 00:01

Maheshwar Ligade


Setting recyclerview item works for me. Outer wrapper relative layout is added intentionally to address issue 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"
android:descendantFocusability="blocksDescendants">

<android.support.v7.widget.RecyclerView
    android:id="@+id/rv_test"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:listitem="@layout/test_item"></android.support.v7.widget.RecyclerView>
</RelativeLayout>
like image 24
Sahar Avatar answered Jan 06 '23 23:01

Sahar