Android教程2020 - 系列总览
本文链接
前面我们的列表中显示的都是同类数据。如果要在一个列表中显示不同类别的数据,该怎么做呢?
RecyclerVIEw已经有应对这类场景的能力,本文描述如何用RecyclerVIEw显示多种内容(item)。
这个例子中涉及到的类和文件比较多。
放在同一个包里的文件
BaseMultIData.javaBaseVH.javaItemTypeDef.javaMultIData1.javaMultIData2.javaMultiItemAdapter.javaOneVH.javaReVIEwDemoMulti.javaTwoVH.java
layout资源文件
item_multi_1.xmlitem_multi_2.xml
场景描述,数据准备首先假设场景。假设我们有2种数据。第一种数据只有1个字符串,第二种数据有2个字符串。
那么我们可以先设计出一个数据的抽象类。并且设计枚举类型来区分这2种数据。
利用枚举类型来区分数据的类别,ItemTypeDef.java
。
public class ItemTypeDef { public static final int ITEM_TYPE_ONE_TEXT = 1; public static final int ITEM_TYPE_2_TEXT = 2; public enum Type { ONE_TEXT(ITEM_TYPE_ONE_TEXT),TWO_TEXT(ITEM_TYPE_2_TEXT); int code; Type(int code) { this.code = code; } public int getCode() { return code; } public static Type getItemTypeByCode(int code) { switch (code) { case ITEM_TYPE_ONE_TEXT: return Type.ONE_TEXT; case ITEM_TYPE_2_TEXT: return Type.TWO_TEXT; } return Type.ONE_TEXT; } }}
枚举类自己带有ordinal()
方法来表明枚举的顺序值。
但这个例子中我们将枚举包裹在一个类里面,并且强行使用了int来标记类别。
数据的抽象类
public abstract class BaseMultIData { public abstract int typeCode();}
表示具体数据的class。
第1种数据class。
public class MultIData1 extends BaseMultIData { private String str1; public MultIData1(String str1) { this.str1 = str1; } public String getStr1() { return str1; } @OverrIDe public int typeCode() { return ItemTypeDef.Type.ONE_TEXT.getCode(); }}
第2种数据class。
public class MultIData2 extends BaseMultIData { private String str1; private String str2; public MultIData2(String str1,String str2) { this.str1 = str1; this.str2 = str2; } public String getStr1() { return str1; } public String getStr2() { return str2; } @OverrIDe public int typeCode() { return ItemTypeDef.Type.TWO_TEXT.getCode(); }}
可以看到,两种数据类分别持有1和2个String。
资源文件前面设计了2种数据,对应的,接下来我们设计2种样式。
layout先准备2种layout。
给第1种数据MultIData1
准备了item_multi_1.xml
。
<?xml version="1.0" enCoding="utf-8"?><linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:layout_wIDth="match_parent" androID:layout_height="40dp" androID:background="#33691E" androID:orIEntation="horizontal"> <TextVIEw androID:ID="@+ID/tv1" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:layout_gravity="center_vertical" androID:layout_marginStart="12dp" androID:textcolor="#ffffff" /></linearLayout>
给第2种数据MultIData2
准备了item_multi_2.xml
<?xml version="1.0" enCoding="utf-8"?><linearLayout xmlns:androID="http://schemas.androID.com/apk/res/androID" androID:layout_wIDth="match_parent" androID:layout_height="50dp" androID:background="#ffffff" androID:orIEntation="horizontal"> <TextVIEw androID:ID="@+ID/tv1" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:layout_gravity="center_vertical" androID:layout_marginStart="12dp" androID:text="tv1" androID:textcolor="#33691E" /> <TextVIEw androID:ID="@+ID/tv2" androID:layout_wIDth="wrap_content" androID:layout_height="wrap_content" androID:layout_gravity="center_vertical" androID:layout_marginStart="12dp" androID:text="tv2" androID:textcolor="#8BC34A" /></linearLayout>
VH设计对应的VIEwHolder。
首先是抽象类BaseVH
。它持有一个ItemTypeDef.Type
来表明自己的类别。
public abstract class BaseVH extends RecyclerVIEw.VIEwHolder { private ItemTypeDef.Type type; public VIEw root; public BaseVH(VIEw itemVIEw,ItemTypeDef.Type type) { super(itemVIEw); this.root = itemVIEw; this.type = type; } public ItemTypeDef.Type getType() { return type; }}
具体实现类。第1种数据的OneVH
。
public class OneVH extends BaseVH { public TextVIEw tv1; public OneVH(VIEw itemVIEw,ItemTypeDef.Type type) { super(itemVIEw,type); tv1 = itemVIEw.findVIEwByID(R.ID.tv1); }}
第2种数据的TwoVH
。
public class TwoVH extends BaseVH { public TextVIEw tv1; public TextVIEw tv2; public TwoVH(VIEw itemVIEw,type); tv1 = itemVIEw.findVIEwByID(R.ID.tv1); tv2 = itemVIEw.findVIEwByID(R.ID.tv2); }}
设计适配器现在2种数据的类和资源都准备好了。我们来设计适配器。RecyclerVIEw.Adapter
中用来区分子项类别的方法是public int getItemVIEwType(int position)
。
我们需要复写这个方法,告诉RecyclerVIEw当前子项的类别。它返回的是int。
@OverrIDe public int getItemVIEwType(int position) { return dataList.get(position).typeCode(); }
适配器完整代码如下
public class MultiItemAdapter extends RecyclerVIEw.Adapter<BaseVH> { private List<BaseMultIData> dataList = new ArrayList<>(); public voID setDataList(List<BaseMultIData> dataList) { this.dataList = dataList; notifyDataSetChanged(); } @NonNull @OverrIDe public BaseVH onCreateVIEwHolder(@NonNull VIEwGroup parent,int vIEwType) { switch (ItemTypeDef.Type.getItemTypeByCode(vIEwType)) { case ONE_TEXT: return new OneVH(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_multi_1,parent,false),ItemTypeDef.Type.ONE_TEXT); case TWO_TEXT: return new TwoVH(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_multi_2,ItemTypeDef.Type.TWO_TEXT); } return null; } @OverrIDe public voID onBindVIEwHolder(@NonNull BaseVH holder,int position) { BaseMultIData data = dataList.get(position); switch (holder.getType()) { case ONE_TEXT: ((OneVH) holder).tv1.setText(((MultIData1) data).getStr1()); break; case TWO_TEXT: TwoVH twoVH = (TwoVH) holder; MultIData2 data2 = (MultIData2) data; twoVH.tv1.setText(data2.getStr1()); twoVH.tv2.setText(data2.getStr2()); break; } } @OverrIDe public int getItemCount() { return dataList.size(); } @OverrIDe public int getItemVIEwType(int position) { return dataList.get(position).typeCode(); }}
要显示多种item,得把它们装在一起。数据列表dataList
声明装载的是抽象类BaseMultIData
。
创建VIEwHolder的onCreateVIEwHolder
方法中,根据vIEwType
来判断应该创建哪一种VIEwHolder。
装配数据的onBindVIEwHolder
方法中,也是根据holder的类别来设置相应的数据。这里用到了强制转换。
在activity中使用这个适配器
public class ReVIEwDemoMulti extends AbsActivity { private MultiItemAdapter mMultiItemAdapter = new MultiItemAdapter(); @OverrIDe protected voID onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentVIEw(R.layout.activity_recyler_vIEw_demo); RecyclerVIEw recyclerVIEw = findVIEwByID(R.ID.re_vIEw); recyclerVIEw.setAdapter(mMultiItemAdapter); recyclerVIEw.setLayoutManager(new linearlayoutmanager(this,RecyclerVIEw.VERTICAL,false)); mMultiItemAdapter.setDataList(genData()); } private List<BaseMultIData> genData() { List<BaseMultIData> List = new ArrayList<>(); for (int i = 0; i < 60; i++) { if (i % 2 == 0) { List.add(new MultIData1("[Data1] " + i)); } else { List.add(new MultIData2("[Data2] " + i,"Type2")); } } return List; }}
运行起来即可看到效果。
这是一个简单的例子 总结
以上是内存溢出为你收集整理的Android教程2020 - RecyclerView显示多种item全部内容,希望文章能够帮你解决Android教程2020 - RecyclerView显示多种item所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)