4

我正在使用回收站视图在我的 android 应用程序中显示卡片列表。早些时候我使用 LinearLayoutManager 为回收器视图设置布局管理器。但是使用此 wrapcontent 值作为回收器视图的高度标记不起作用,它覆盖了整个应用程序屏幕。在这个问题中使用@davkutalek 回答How do I make WRAP_CONTENT work on a 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);
    }
}
}

使用这个类,即使我没有用任何数据填充我的回收站视图,也会始终显示一张空卡片如果我使用一些数据来填充回收站视图,那么这个空卡片会显示在所有卡片的末尾。

截图一:

截图二:

使用日志我发现 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);
        }
    }
}

我搜索了可能的原因,但找不到任何原因。任何解释和建议表示赞赏。

4

0 回答 0