在日常使用手机的时候,我们经常会遇到如下所示的现象,即一个可以上下滑动的界面,里面存在多条不同格式的不同数据,每个看起来都一样,实际上又不太一样。
这种现象在Android里面可以简单的理解为一个recycle view里面写了多个不同的item(示例展示的就是写了三个item)我们都知道大部分情况使用recycle view的时候都是写一个item,那像这种多个item的时候我们应该怎么实现呢?
像平时写一个item的时候通常是这样写的:
//onCreateViewHolder 加载布局文件 按需加载
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(ReMenHuoDongActivity.this)
.inflate(R.layout.rmhd_item_layout,parent,false);
return new MyViewHolder(view);
}
而我们要实现多个item(举例就是写三个item了)就应该至少要写三个view对象吗?显然不用那样,我们可以通过switch
语句根据viewType
的不同值来决定使用哪种布局来创建视图。
对于每种viewType
,使用LayoutInflater
从parent
的上下文中膨胀(inflate)对应的布局文件,并将其存储在view
变量中。这里写的ITEM_TYPE_1
,ITEM_TYPE_2
和ITEM_TYPE_3
是在适配器中定义的整型常量
private static final int ITEM_TYPE_1 = 1;
private static final int ITEM_TYPE_2 = 2;
private static final int ITEM_TYPE_3 = 3;
@NonNull
@Override
// onCreateViewHolder 加载布局文件 按需加载
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view;
switch (viewType) {
case ITEM_TYPE_1:
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.dzf_item_layout, parent, false);
break;
case ITEM_TYPE_2:
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.xxz_item_layout, parent, false);
break;
case ITEM_TYPE_3:
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.yjs_item_layout, parent, false);
break;
default:
throw new IllegalArgumentException("Invalid view type");
}
return new MyViewHolder(view);
}
当然我们在加载item的时候还需要对里面的控件进行操作(对于不同item中控件的申明就不在赘述)
// onBindViewHolder 操作item中的控件
@Override
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
// 根据位置设置数据,这里根据实际情况设置不同的数据
switch (getItemViewType(position)) {
case ITEM_TYPE_1:
// 设置 item1 的数据
break;
case ITEM_TYPE_2:
// 设置 item2 的数据
case ITEM_TYPE_3:
// 设置 item3 的数据
break;
}
}
其中getItemViewType()方法和返回的item条数如下所示:
(这里假设chatList,chatList2,chatList3是存储不同item需要的数据来源的数组,具体需要实现的逻辑根据需求来变化即可)
// 显示的item的条数
@Override
public int getItemCount() {
// 返回所有布局文件的 item 数量总和
int num = chatList.size() + chatList2.size() + chatList3.size();
Log.i("num", String.valueOf(num));
return num;
}
@Override
public int getItemViewType(int position) {
if (position < chatList.size()) {
return ITEM_TYPE_1;
} else if (position <chatList.size() + chatList2.size()) {
return ITEM_TYPE_2;
} else {
return ITEM_TYPE_3;
}
}
对于getItemViewType()方法的理解就是,根据传来的position值(每个item都有一个position值,值从0开始递增),来判断这个位置需要展示哪一种item,而返回的总条数就是数据的总大小啦
以下是我写的一个示例
假设我们的第一种item的数据来源的list大小是3,那么当position的值为0,1,2的时候都是显示第一种item,后面以此类推。
在我们已经成功申明并且书写了适配器之后就能实现一个recycle view里面显示多个不同的item啦~
RecyclerView recyclerView;
MyAdapter myAdapter;
....
protected void onCreate(Bundle savedInstanceState) {
...
recyclerView = findViewById(R.id.recyclerView);
myAdapter = new MyAdapter();
recyclerView.setAdapter(myAdapter);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
}
(最终的效果图也就是文章开篇动图啦)