4

I am using recycler view to display list of cards in my android app. Earlier i was using LinearLayoutManager to set layout manager for recycler view. But using this wrapcontent value for height tag of recycler view was not working and it covered whole app screen. Using @davkutalek answer in this question How do I make WRAP_CONTENT work on a RecyclerView i was able to set recyclerview height to wrap content

This is my CustomLinearLayoutManager Class

public class CustomLinearLayoutManager extends LinearLayoutManager {

public CustomLinearLayoutManager(Context context) {
    super(context);
}
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,
                widthSpec,
                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) {

    View view = recycler.getViewForPosition(position);

    // For adding Item Decor Insets to view
    super.measureChildWithMargins(view, 0, 0);
    if (view != null) {
        RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams();
        int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec,
                getPaddingLeft() + getPaddingRight() + getDecoratedLeft(view) + getDecoratedRight(view), p.width);
        int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec,
                getPaddingTop() + getPaddingBottom() + getPaddingBottom() + getDecoratedBottom(view), p.height);
        view.measure(childWidthSpec, childHeightSpec);

        // Get decorated measurements
        measuredDimension[0] = getDecoratedMeasuredWidth(view) + p.leftMargin + p.rightMargin;
        measuredDimension[1] = getDecoratedMeasuredHeight(view) + p.bottomMargin + p.topMargin;
        recycler.recycleView(view);
    }
}
}

Using this class, a empty card is always shown even if i havent populated my recycler view with any data If i use some data to populate recycler view then this empty card is shown at the end of all cards.

Screenshot 1:

Screenshot 2:

Using Logs i found out onMeasure() method is called twice with same data.

This is my Fragment which uses recyclerview

private ContentTestResult contentTestResult;
private RVAdapter rvAdapter;
private RecyclerView recyclerView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    View view = inflater.inflate(R.layout.fragment_test_result, container, false);

    contentTestResult = new ContentTestResult();
    recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView_card_test);
    recyclerView.setHasFixedSize(false);
//        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity());
    CustomLinearLayoutManager linearLayoutManager = new CustomLinearLayoutManager(getActivity());
    recyclerView.setLayoutManager(linearLayoutManager);

    contentTestResult.clear();
//        contentTestResult.addItem(new ContentTestResult.DummyItem("ABC", "XYZ", 1));
//        contentTestResult.addItem(new ContentTestResult.DummyItem("EFG", "MNO", 2));

    rvAdapter=new RVAdapter(contentTestResult.ITEMS);
    recyclerView.setAdapter(rvAdapter);

    return view;
}

private class RVAdapter extends RecyclerView.Adapter<RVAdapter.CardViewHolder> {
    ContentTestResult content = new ContentTestResult();

    public RVAdapter ( List<ContentTestResult.DummyItem> list_dummy ){
        content.ITEMS = list_dummy;
    }

    @Override
    public RVAdapter.CardViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.card_test_result, parent, false );
        CardViewHolder cardViewHolder = new CardViewHolder( view );
        return cardViewHolder;
    }

    @Override
    public void onBindViewHolder(RVAdapter.CardViewHolder holder, int position) {
        holder.place.setText(content.ITEMS.get(position).place);
        holder.near.setText("Near " + content.ITEMS.get(position).near);
        holder.price.setText("No. " + content.ITEMS.get(position).price);
    }

    @Override
    public int getItemCount() {
        return content.ITEMS.size();
    }

    public class CardViewHolder extends RecyclerView.ViewHolder {
        CardView cardView;
        TextView place, near, price;

        public CardViewHolder(View itemView) {
            super(itemView);
            cardView = (CardView) itemView.findViewById(R.id.cardView_card_test);
            place = (TextView) itemView.findViewById(R.id.text_card_test_place);
            near = (TextView) itemView.findViewById(R.id.text_card_test_near);
            price = (TextView) itemView.findViewById(R.id.text_card_test_price);
        }
    }
}

I searched for possible reasons but couldnt find any. Any explanation and suggestion is appreciated.

Community
  • 1
  • 1
Aditya Verma
  • 91
  • 1
  • 10
  • take a look at this http://stackoverflow.com/questions/28521008/recyclerview-adapter-is-showing-blank-cardview – johnrao07 Jan 07 '16 at 09:40
  • @johnrao07 i think above stated problem isn't my case because firstly, i am facing this problem irrespective of api level. Secondly, i am getting an empty card in the end when i try to populate my recycler view. My concern isnt much about an empty card when there is no data, my major concern is about an empty card i get at the end of all cards. As in all case i would populate the recycler view. – Aditya Verma Jan 07 '16 at 11:58

0 Answers0