RecyclerView使用指南(二)——|RecyclerView使用指南(二)—— 多种ItemLayout

【RecyclerView使用指南(二)——|RecyclerView使用指南(二)—— 多种ItemLayout】声明:原创作品,转载请注明出处:https://www.jianshu.com/p/7d30ba789a46
我在上一篇文章《RecyclerView使用指南(一)—— 基本使用》中讲解了RecyclerView的最基本用法。
这一篇,我来讲解一下多种条目布局应该如何显示。(如果没看过上一篇文章的小朋友,建议去看一下短小的上一篇文章。。。)
没图说个**:
RecyclerView使用指南(二)——|RecyclerView使用指南(二)—— 多种ItemLayout
文章图片

  • 核心思路:
  1. 针对不同的条目布局,我们创建不同的ViewHolder。
  2. Adapter需要知道在什么情况下使用什么样的布局。
Adapter中,我们可以通过重写getItemViewType(int position)方法,根据数据源,返回不同的viewType,Adapter在onCreateViewHolder和onBindViewHolder方法中使用这个值来创建ViewHolder和绑定相应的数据。
一、数据源为同种类型 总上所述,我们可以写一个简单的示例代码,它的数据源都是Data类型。如下:
package com.liuym.myapplication; import android.support.annotation.NonNull; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import java.util.List; public class RvAdapter extends RecyclerView.Adapter { //条目类型 public static final int TYPE_0 = 0; public static final int TYPE_1 = 1; //数据源 private List mList; public RvAdapter(List list) { mList = list; }@NonNull @Override public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) { View item; RecyclerView.ViewHolder holder = null; if (viewType == TYPE_0) { item = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_rv_type1, viewGroup, false); holder = new Type0ViewHolder(item); } if (viewType == TYPE_1) { item = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_rv_type2, viewGroup, false); holder = new Type1ViewHolder(item); } return holder; }/** * 根据数据源的某一项,返回相应的布局类别 * * @param position * @return */ @Override public int getItemViewType(int position) { return mList.get(position).getType(); }@Override public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) { int type = getItemViewType(i); Data data = https://www.it610.com/article/mList.get(i); if (type == TYPE_0) { Type0ViewHolder holder = (Type0ViewHolder) viewHolder; holder.iv.setImageResource(R.drawable.ic_launcher_background); holder.tv.setText(data.getText()); } if (type == TYPE_1) { Type1ViewHolder holder = (Type1ViewHolder) viewHolder; holder.iv.setImageResource(R.drawable.ic_launcher_background); holder.tv.setText(data.getText()); } }@Override public int getItemCount() { return mList == null ? 0 : mList.size(); }class Type0ViewHolder extends RecyclerView.ViewHolder { ImageView iv; TextView tv; public Type0ViewHolder(@NonNull View itemView) { super(itemView); iv = itemView.findViewById(R.id.iv); tv = itemView.findViewById(R.id.tv); } }class Type1ViewHolder extends RecyclerView.ViewHolder { ImageView iv; TextView tv; public Type1ViewHolder(@NonNull View itemView) { super(itemView); iv = itemView.findViewById(R.id.iv); tv = itemView.findViewById(R.id.tv); } } }

二、数据源为不同类型 那么,如果我们要显示不同种类型的怎么办呢?比如这个列表既包含铅笔,又包含橡皮,怎么办?
这里,我们的数据源要包含两个类:Pencil类和Eraser类,为了将它们放到同一个列表中,我们可以让它们实现同一个接口,讲到这里,是不是有思路了呢?
好,我们来实现这个功能!
  1. 创建一个接口:
package com.liuym.myapplication; public interface IMultiType { /** * 返回条目类型 * * @return */ int getItemType(); }

  1. 创建Pencil类实现IMultiType接口(Eraser类和Pencil类基本一致,只是返回的itemType不同):
package com.liuym.myapplication; public class Pencil implements IMultiType { private String msg; public Pencil(String msg) { this.msg = msg; }public String getMsg() { return msg; }public void setMsg(String msg) { this.msg = msg; }@Override public int getItemType() { return RvAdapter.TYPE_PENCIL; } }

  1. 修改Adapter的数据源,将IMultiType的子类放入到数据源中,重写getItemViewType(int position)方法,完整代码如下:
package com.liuym.myapplication; import android.support.annotation.NonNull; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import java.util.List; public class RvAdapter extends RecyclerView.Adapter { //条目类型 public static final int TYPE_PENCIL = 0; public static final int TYPE_ERASER = 1; //数据源 private List mList; public RvAdapter(List list) { mList = list; }@NonNull @Override public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) { View item; RecyclerView.ViewHolder holder = null; if (viewType == TYPE_PENCIL) { item = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_rv_type1, viewGroup, false); holder = new PencilViewHolder(item); } if (viewType == TYPE_ERASER) { item = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item_rv_type2, viewGroup, false); holder = new EraserViewHolder(item); } return holder; }/** * 根据数据源的某一项,返回相应的布局类别 * * @param position * @return */ @Override public int getItemViewType(int position) { return mList.get(position).getItemType(); }@Override public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) { int type = getItemViewType(i); if (type == TYPE_PENCIL) { Pencil pencil = (Pencil) mList.get(i); PencilViewHolder holder = (PencilViewHolder) viewHolder; holder.iv.setImageResource(R.drawable.ic_launcher_background); holder.tv.setText(pencil.getMsg()); } if (type == TYPE_ERASER) { Eraser eraser = (Eraser) mList.get(i); EraserViewHolder holder = (EraserViewHolder) viewHolder; holder.iv.setImageResource(R.drawable.ic_launcher_background); holder.tv.setText(eraser.getMsg()); } }@Override public int getItemCount() { return mList == null ? 0 : mList.size(); }class PencilViewHolder extends RecyclerView.ViewHolder { ImageView iv; TextView tv; public PencilViewHolder(@NonNull View itemView) { super(itemView); iv = itemView.findViewById(R.id.iv); tv = itemView.findViewById(R.id.tv); } }class EraserViewHolder extends RecyclerView.ViewHolder { ImageView iv; TextView tv; public EraserViewHolder(@NonNull View itemView) { super(itemView); iv = itemView.findViewById(R.id.iv); tv = itemView.findViewById(R.id.tv); } } }

  1. 设置数据源给Adapter,并将Adapter设置给RecyclerView
private void initRv() { List list = new ArrayList<>(); for (int i = 0; i < 20; i++) { if (i % 2 == 0) { String msg = String.format("eraser: %1s", i); list.add(new Eraser(msg)); } else { String msg = String.format("pencil: %1s", i); list.add(new Pencil(msg)); } } RecyclerView recyclerView = findViewById(R.id.rv); RvAdapter adapter = new RvAdapter(list); recyclerView.setAdapter(adapter); }

总结 这一篇,我讲解了如何在RecyclerView中使用不同的布局,下一篇,我会讲解如何给RecyclerView添加分割线以及给Item设置点击事件。
系列文章 《RecyclerView使用指南(一)—— 基本使用》
《RecyclerView使用指南(二)—— 多种ItemLayout》
《RecyclerView使用指南(三)—— 添加分割线和点击事件》
《RecyclerView使用指南(四)—— 使用ItemDecoration》
《RecyclerView使用指南(五)—— 实现吸顶效果》

    推荐阅读