RecycleView是开发中最常用的组件之一,因其优秀的回收机制而得到了广泛使用。最常用的效果就是用来实现复杂多布局列表。
所以当项目里需要实现如下布局时,我最先想到的便是使用Recycleview。
可以看到,整个Recycleview是方向垂直,而第一个itrm中有个水平滑动的recycleview。
而我们的demo实现的效果如图:
现在让我们开始实现这一步骤:
1.先编写三个不同类型的item
2.在Adapter中分别三种布局对应的ViewHolder
3.1 即使有多种type,Adapter中的集合实体类也是使用的同一个,所以,我们要先写一个实体类
public class MultiBean {
int type;
String itemText;
// 横向的数据集合
ArrayList arrayList;
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getItemText() {
return itemText;
}
public void setItemText(String itemText) {
this.itemText = itemText;
}
public ArrayList getArrayList() {
return arrayList;
}
public void setArrayList(ArrayList arrayList) {
this.arrayList = arrayList;
}
}
3.2在Adapter中,为了区分三种布局,我们需要重写 getItemViewType(int position)方法,然后在onCreateViewHolder(@NonNull ViewGroup parent, int viewType)方法中加载不同的布局,返回对应的viewHolder
@Override
public int getItemViewType(int position) {
MultiBean multiBean = multiBeans.get(position);
ArrayList arrayList = multiBean.getArrayList();
if (arrayList!=null&&arrayList.size()>0){
return TYPE_HORIZONTAL;
}else if (TextUtils.isEmpty(multiBean.getItemText())){
return TYPE_TITLE;
}else {
return TYPE_VERYICAL;
}
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view;
switch (viewType) {
case TYPE_HORIZONTAL://水平布局是个单独的recycleview
view = inflater.inflate(R.layout.item_recycle, parent, false);
return new ViewHorizVH(view);
case TYPE_TITLE:
view = inflater.inflate(R.layout.item_title, parent, false);
return new ViewTitleVH(view);
case TYPE_VERYICAL:
view = inflater.inflate(R.layout.item_vertival, parent, false);
return new ViewVerticalVH(view);
}
return null;
}
3.3 在onBindViewHolder 中,区别三种布局,并绑定数据。
int type = multiBeans.get(position).getType();
switch (type) {
case TYPE_HORIZONTAL:
ViewHorizVH horizVH = (ViewHorizVH) holder;
break;
case TYPE_TITLE:
ViewTitleVH titleVH = (ViewTitleVH) holder;
break;
case TYPE_VERYICAL:
ViewVerticalVH verticalVH = (ViewVerticalVH) holder;
break;
default:
break;
}
现在,我们的Adapter已经编写好了,在Activity中使用即可。
4.填充假数据
private void initData() {
beans = new ArrayList<>();
// 水平数据
ArrayList strings = new ArrayList<>();
for (int i = 0; i < 10; i++) {
strings.add("横向Item" + i);
}
MultiBean multiBean;
for (int i = 0; i < 50; i++) {
multiBean = new MultiBean();
int num = i % 10;
switch (num) {
case 0:
multiBean.setType(0);
multiBean.setArrayList(strings);
break;
case 1:
multiBean.setType(1);
break;
default:
multiBean.setType(2);
multiBean.setItemText("垂直Item:" + i);
break;
}
beans.add(multiBean);
}
}
private void initView() {
recycle_public = findViewById(R.id.recycle_public);
adapter = new MultiAdapter(beans, this);
recycle_public.setAdapter(adapter);
RecyclerView.LayoutManager lm = new LinearLayoutManager(this);
((LinearLayoutManager) lm).setOrientation(RecyclerView.VERTICAL);
recycle_public.setLayoutManager(lm);
// 设置间隔线
recycle_public.addItemDecoration(new DividerItemDecoration(this,DividerItemDecoration.VERTICAL));
}
好了,到这一步为止,多布局的适配器以及数据已经填充好了,接下来我们需要给这个recycleview加上点击事件。
5.添加点击事件:
5.1定义接口:
public interface MultiClickListener {
void onClick(View view,
int position1,
Object obj,
int type);
}
5.2 在适配器中使用:
private MultiClickListener clickListener;
public void setClickListener(MultiClickListener clickListener) {
this.clickListener = clickListener;
}
// onBindViewHolder 中设置点击事件
verticalVH.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (clickListener != null) {
clickListener.onClick(view, position,multiBeans.get(position).getItemText(), TYPE_VERYICAL);
}
}
});
然后再Activity设置点击监听:
adapter.setClickListener(new MultiClickListener() {
@Override
public void onClick(View view, int position1, Object obj, int type) {
LogUtils.i(obj.toString());
}
});
现在我们在控制台查看一下输出:
OK,已经大功告成了。
因横向滑动的item只是一个recycleview,需要在onBindViewHolder中初始化,设置数据,并添加点击事件,其代码与逻辑跟上述类似,就不在这里展开了,需要的同学可以在github上查看项目。
注意:区分item的布局方式其实是有两种,一种是通过Adapter的方法getItemViewType来实现,这种方式在开发中用的比较多。
但是还有一种,是在实体类中设置单独的字段type来区别,这一种的局限性就在于,实际接口中使用的数据几乎不会有这个字段,需要经过二次加工。
个人建议使用第一种方式来区分。
附上github地址:https://github.com/zhang-yanpeng/RiverPlayer