具有多种布局的 RecyclerView

RecyclerView With Multiple Layouts

我正在使用 RecyclerView 在 CardView 中显示文本,但我想在 RecyclerView 的顶部添加一个 Header TextView,如下所示:

所以我制作了另一个只有 TextView 的布局文件 "top_header.xml",但我不确定如何修改适配器以在其中获取两种布局。

public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> {

List<AdapterData> mItems;

public Adapter() {
    super();
    mItems = new ArrayList<AdapterData>();
    AdapterData data = new AdapterData();
    data.setCode("dummytext");
    data.setResult("dummytext");
    mItems.add(data);

    data = new AdapterData();
    data.setCode("dummytext");
    data.setResult("dummytext");
    mItems.add(data);

    data = new AdapterData();
    data.setCode("dummytext");
    data.setResult("dummytext");
    mItems.add(data);

    data = new AdapterData();
    data.setCode("dummytext");
    data.setResult("dummytext");
    mItems.add(data);

    data = new AdapterData();
    data.setCode("dummytext");
    data.setResult("dummytext");
    mItems.add(data);

}

@Override
public int getItemViewType(int position) {
    int viewType = 0;
    return viewType;
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    if (viewType == 0) {
        return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.top_textview, parent, false));
    }

    return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.recycler_view_card_item, parent, false));
}

@Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {
    AdapterData data = mItems.get(position);
    viewHolder.code.setText(data.getCode());
    viewHolder.result.setText(data.getResult());

}


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


class ViewHolder1 extends RecyclerView.ViewHolder{
    public TextView header;

    public ViewHolder1(View itemView) {
        super(itemView);
        header = (TextView)itemView.findViewById(R.id.header_textview);

    }
}

class ViewHolder2 extends RecyclerView.ViewHolder{
    public TextView code;
    public TextView result;

    public ViewHolder2(View itemView) {
        super(itemView);
        code = (TextView)itemView.findViewById(R.id.sims_code);
        result = (TextView)itemView.findViewById(R.id.sims_result);

    }
}


}

您需要进行三处更改:

  1. 在您的 RecyclerView.Adapter 上实施 getItemViewType(),根据提供的 position,为您的应用所需的每种视图类型 return 一个唯一的整数].因此,您会 return 为您的 header 设置一个值(大概是 0position),为其他所有设置设置另一个值。

  2. 注意传入onCreateViewHolder()viewType参数,根据需要创建合适的RecyclerView.ViewHolder。这反过来可能意味着您应该为 header 和详细信息行设置不同的 ViewHolder 类。

  3. onBindViewHolder() 中,根据您获得的 ViewHolder 的类型应用绑定逻辑,因此您将适当的数据绑定到 ViewHolder。您可以使用 instanceof,或者让 ViewHolder 类 实现一个公共接口,或者任何使它工作的东西。

This sample app 演示了 RecyclerView 部分 headers 实现上述步骤。

必须创建不同类型的 View holder 并且还要根据 view holder 视图绑定数据。这个问题已经被问到并在这里回答Recyclerview and handling different type of row inflation,它会对你有帮助

如果你想添加多种类型的视图(超过 2 种类型)而不仅仅是 header 和 "normal" itemCommonsWare answer 是完美的。但是如果上面提到的两种类型(headeritem)对你来说足够了,那么答案会简单很多(从实际的角度来看)。

您可以使用两个相对简单的库:

  1. RecyclerViewHeader - 使用超级简单,但使用了一点 "hacky" 方法,有时会导致问题。适合比较简单的headers.

  2. HeaderRecyclerView - Suitable for any type of header. Implements approach mentioned by CommonsWare 膨胀两种类型的视图。比 RecyclerViewHeader 更难使用,但日常使用并不难。

公开:我是RecyclerViewHeader的作者。我知道它的缺陷,因此我并不是要将其作为 one-for-all 解决方案进行推广,而是将其作为使适配器复杂化的有趣替代方案。 HeaderRecyclerView 是一段很好的代码,可以简化您的工作。当我的 RecyclerView header 变得复杂时,我自己使用它。