在做项目的过程中,我们会经常用到RecycleView来实现各种列表,但有时候我们也会遇到多布局的列表,今天我们来讲解一下RecycleView的多布局的实现方式及思路。
效果图奉上

1、 单布局的Adapter
首先看下以前的单一布局是如何实现的:
我们继承RecycleView.Adapter,泛型是MyAdapter 中继承的ViewHolder类,这样写后我们的onCreateViewHolder和onBindViewHolder的方法参数都是我们的ViewHolder了,没有办法实现多布局的区分
public class MoreLayoutAdapter extends RecyclerView.Adapter<MoreLayoutAdapter.ViewHolder> {
@NonNull
@Override
public MoreLayoutAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
return null;
}
@Override
public void onBindViewHolder(@NonNull MoreLayoutAdapter.ViewHolder viewHolder, int i) {
}
@Override
public int getItemCount() {
return 0;
}
public class ViewHolder extends RecyclerView.ViewHolder{
public ViewHolder(@NonNull View itemView) {
super(itemView);
}
}
二、 多布局的Adapter
多布局的Adapter我们泛型为RecyclerView.ViewHolder,通过ViewType,我们区分使用不同的ViewHolder。
我们首先定义四个标志
//定义四种常量 表示四种条目类型
public static final int TYPE_TITLE = 1;
public static final int TYPE_TOP = 2;
public static final int TYPE_CENTER = 3;
public static final int TYPE_BOTTOM = 4;
RecyclerView提供了方法去区分ViewType,布局的类型要从Activity的传入到适配器里,用于和ViewType做匹配。
@Override
public int getItemViewType(int position) {
SearchSecondHouseBean.DataBean.ErshoufangBean ershoufangBean = mErshoufangBeanList.get(position);
if (ershoufangBean.getDatatype() == 1) {
return TYPE_TITLE;
} else if (ershoufangBean.getDatatype() == 2) {
return TYPE_TOP;
} else if (ershoufangBean.getDatatype() == 3) {
return TYPE_CENTER;
} else {
return TYPE_BOTTOM;
}
}
onCreateViewHolder的第二个参数int viewType就是getItemViewType的返回值
public class MoreLayoutAdapter extends RecyclerView.Adapter<MoreLayoutAdapter.ViewHolder>{
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
View inflate;
RecyclerView.ViewHolder holder = null;
if (viewType == TYPE_TITLE) {
inflate = LayoutInflater.from(mContext).inflate(R.layout.item_agent_card, viewGroup, false);
return new TitleViewHolder(inflate);
} else if (viewType == TYPE_TOP) {
inflate = LayoutInflater.from(mContext).inflate(R.layout.item_second_good_house, viewGroup, false);
return new ViewHolder(inflate);
} else if (viewType == TYPE_CENTER) {
inflate = LayoutInflater.from(mContext).inflate(R.layout.item_search_house_tuijian, viewGroup, false);
return new CenterViewHolder(inflate);
} else {
inflate = LayoutInflater.from(mContext).inflate(R.layout.item_second_good_house, viewGroup, false);
return new BottomViewHolder(inflate);
}
}
在onBindViewHolder中,我们的来绑定数据
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position){
if (viewHolder instanceof TitleViewHolder) {
SearchSecondHouseBean.DataBean.ErshoufangBean bean = mErshoufangBeanList.get(i);
Glide.with(mContext).load(bean.getFengmian()).apply(new RequestOptions().placeholder(R.drawable.default_bd).transform(new GlideRoundTransform(mContext))).into(((TitleViewHolder) viewHolder).mCivAgentCardIcon);
((TitleViewHolder) viewHolder).mTvAgentCardHouseName.setText(bean.getXiaoqu());
}else if (viewHolder instanceof CenterViewHolder) {
SearchSecondHouseBean.DataBean.ErshoufangBean ershoufangBean = mErshoufangBeanList.get(i);
((CenterViewHolder) viewHolder).mTvTuiJianText.setText(ershoufangBean.getFangxing());
} else if (viewHolder instanceof BottomViewHolder) {
SearchSecondHouseBean.DataBean.ErshoufangBean bean = mErshoufangBeanList.get(i);
Glide.with(mContext).load(bean.getFengmian()).apply(new RequestOptions().placeholder(R.drawable.default_bd).transform(new GlideRoundTransform(mContext))).into(((BottomViewHolder) viewHolder).mIvSecondGoodHouseIcon);
}
ViewHolder的创建
public class CenterViewHolder extends RecyclerView.ViewHolder {
TextView mTvTuiJianText;
public CenterViewHolder(@NonNull View itemView) {
super(itemView);
mTvTuiJianText = itemView.findViewById(R.id.tv_tuijian_text);
}
}
到这里基本就搞定了。
通过RecyclerView.Adapter设置多布局是非常方便的,而且大家可以发现当RecyclerView为LinearLayoutManager,我们可以通过viewType给RecyclerView来设置Header和Footer,如
public static final int HEADER = 1;
public static final int FOOTER = 2;
public static final int ITEM = 3;
@Override
public int getItemViewType(int position) {
if(position == 0){
return HEADER;
}else if(position == getItemCount() -1){
return FOOTER;
}else{
return ITEM;
}
}
@Override
public int getItemCount() {
return mDatas.size() + 2;//Header和Footer
}
但是当布局管理器为GridLayoutManager和StaggeredGridLayoutManager时就要不能这样去做了。
补充知识点:
了解一下子adapter的加载顺序
- getItemViewType(int position)
2.onCreateViewHolder(@NonNull ViewGroup viewGroup, int i)
3.onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, final int i)
其中第二步会把item的布局加载进来 与viewholder关联
第三步会把数据与viewhoder关联
网友评论