Custom Linear Layout Manager добавя празна карта към recyclerView

Използвам изглед за рециклиране, за да покажа списък с карти в моето приложение за 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 мисля, че горепосоченият проблем не е моят случай, защото първо, аз съм изправен пред този проблем, независимо от нивото на API. Второ, накрая получавам празна карта, когато се опитвам да попълня изгледа си за рециклиране. Притеснението ми не е много за празна карта, когато няма данни, основното ми притеснение е за празна карта, която получавам в края на всички карти. Както във всички случаи, бих попълнил изгледа за рециклиране.   -  person Aditya Verma    schedule 07.01.2016