Custom Linear Layout Manager добавляет пустую карту в recyclerView

Я использую представление recycler для отображения списка карт в моем приложении для Android. Раньше я использовал LinearLayoutManager, чтобы установить менеджер компоновки для просмотра ресайклера. Но использование этого значения wrapcontent для тега высоты в представлении переработчика не работало и покрывало весь экран приложения. Использование ответа @davkutalek в этом вопросе Как мне сделать WRAP_CONTENT работать с RecyclerView я смог установить высоту recyclerview для переноса содержимого

Это мой класс CustomLinearLayoutManager

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

Используя этот класс, всегда отображается пустая карточка, даже если я не заполнил свое представление ресайклера какими-либо данными. Если я использую некоторые данные для заполнения представления ресайклера, тогда эта пустая карточка отображается в конце всех карточек.

Скриншот 1:

Скриншот 2:

Используя журналы, я обнаружил, что метод onMeasure() вызывается дважды с одними и теми же данными.

Это мой фрагмент, который использует 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);
        }
    }
}

Искал возможные причины, но не нашел. Любое объяснение и предложение приветствуются.


person Aditya Verma    schedule 07.01.2016    source источник
comment
взгляните на этот stackoverflow.com/questions /28521008/   -  person johnrao07    schedule 07.01.2016
comment
@ johnrao07 johnrao07 Я думаю, что вышеуказанная проблема не в моем случае, потому что, во-первых, я сталкиваюсь с этой проблемой независимо от уровня API. Во-вторых, я получаю пустую карту в конце, когда пытаюсь заполнить свое представление ресайклера. Меня беспокоит не пустая карта, когда нет данных, меня больше всего беспокоит пустая карта, которую я получаю в конце всех карт. Как и во всех случаях, я бы заполнил представление ресайклера.   -  person Aditya Verma    schedule 07.01.2016