创建一个多布局基类BaseMultiItemEntity
public class BaseMultiItemEntity {
private int itemType;
public BaseMultiItemEntity(@LayoutRes int itemType) {
this.itemType = itemType;
}
public int getItemType() {
return itemType;
}
public void setItemType(@LayoutRes int itemType) {
this.itemType = itemType;
}
}
多布局实体类必须继承BaseMultiItemEntity
public class MultiItemEntity extends BaseMultiItemEntity {
private String name;
private String pass;
public MultiItemEntity(int itemType, String name, String pass) {
super(itemType);
this.name = name;
this.pass = pass;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPass() {
return pass;
}
public void setPass(String pass) {
this.pass = pass;
}
}
public abstract class BaseMultiItemAdapter extends BaseRecyclerViewAdapter{
public BaseMultiItemAdapter(@Nullable List data) {
super(data);
}
@Override
public int getItemViewType(int position) {
return data.get(position).getItemType();
}
}
在BaseRecyclerViewAdapter添加以下代码
//是否是多布局
private boolean isMultiItem = false;
/**
* 单布局构造函数
* @param resource 布局文件
* @param data item数据
*/
public BaseRecyclerViewAdapter(@LayoutRes int resource, @Nullable List data){
this.data = data == null ? new ArrayList() : data;
if (resource != 0) {
this.resource = resource;
isMultiItem = false;
}
}
/**
* 多布局的类型
*/
private SparseIntArray layouts;
private int getLayoutId(@LayoutRes int viewType) {
return layouts.get(viewType);
}
/**
* 多布局构造函数
* @param data item数据
*/
protected BaseRecyclerViewAdapter(@Nullable List data) {
this(0, data);
isMultiItem = true;
layouts = new SparseIntArray();
baseMultiItemEntities = (List) data;
if (baseMultiItemEntities != null) {
for (BaseMultiItemEntity t :baseMultiItemEntities){
layouts.put(t.getItemType(), t.getItemType());
}
}
}
修改BaseRecyclerViewAdapter的onCreateViewHolder方法
@NonNull
@Override
public K onCreateViewHolder(@NonNull ViewGroup viewGroup, int viewType) {
context = viewGroup.getContext();
Application application = (Application) context.getApplicationContext();
View view;
LayoutInflater mLayoutInflater = LayoutInflater.from(context);
if (isMultiItem){
view = mLayoutInflater.inflate(getLayoutId(viewType), viewGroup, false);
}else {
view = mLayoutInflater.inflate(resource, viewGroup, false);
}
K baseViewHolder = createBaseViewHolder(view);
bindViewClickListener(baseViewHolder);
baseViewHolder.setAdapter(this, application);
return baseViewHolder;
}
在Activity中
val list = ArrayList()
list.add(MultiItemEntity(R.layout.item,"12","34"))
list.add(MultiItemEntity(R.layout.item2,"12","34"))
list.add(MultiItemEntity(R.layout.item,"12","34"))
val adapter = MultiItemAdapter(list)
recyclerView.layoutManager = LinearLayoutManager(this)
recyclerView.adapter = adapter
适配器
public class MultiItemAdapter extends BaseMultiItemAdapter {
public MultiItemAdapter(@Nullable List data) {
super(data);
}
@Override
public void convert(@NonNull BaseViewHolder holder, MultiItemEntity item, int position) {
switch (holder.getItemViewType()){
case R.layout.item:
holder.setText(R.id.textView2,item.getName()+item.getPass());
holder.addOnClickListener(R.id.imageView).addOnLongClickListener(R.id.imageView);
holder.addOnClickListener(R.id.textView2).addOnLongClickListener(R.id.textView2);
break;
case R.layout.item2:
holder.setText(R.id.textView,item.getName()+item.getPass())
.setText(R.id.textView2,item.getName())
.addOnClickListener(R.id.imageView).addOnLongClickListener(R.id.imageView)
.addOnClickListener(R.id.textView2).addOnLongClickListener(R.id.textView2)
.addOnClickListener(R.id.textView).addOnLongClickListener(R.id.textView);
break;
}
}
}
在数据更新时会使用这样一个方法,这个方法在一般的时候是没有问题的。
/**
* 在列表最后添加一个item
* @param element item的数据
*/
public void addNewItem(@NonNull T element) {
data.add(element);
notifyItemInserted(data.size());
compatibilityDataSizeChanged(1);
}
但如果添加的是一个新的布局,调用这个方法是会报错的,因为找不到该类型
adapter.addNewItem(MultiItemEntity(R.layout.item3,"12","34"))
有什么办法解决这个问题呢,有两种方式
方式一:
更新数据前调用以下方法添加新布局
/**
* 添加新布局
* @param viewType 新布局
*/
public void setLayouts(@LayoutRes int viewType){
layouts.put(viewType,viewType);
}
方式二:
在更新数据前判断是不是多布局,再判断是不是新布局
/**
* 是否是新布局
* @param element BaseMultiItemEntity
*/
public void isNewLayout(@NonNull T element){
if (isMultiItem){
int itemType = ((BaseMultiItemEntity) element).getItemType();
if (getLayoutId(itemType) == 0 ){
layouts.put(itemType,itemType);
}
}
}
/**
* 是否是新布局
* @param newData BaseMultiItemEntity集合
*/
private void isNewLayout(@NonNull Collection extends T> newData){
if (isMultiItem){
for (T element :newData){
int itemType = ((BaseMultiItemEntity) element).getItemType();
if (getLayoutId(itemType) == 0 ){
layouts.put(itemType,itemType);
}
}
}
}
/**
* 在列表最后添加一个item
* @param element item的数据
*/
public void addNewItem(@NonNull T element) {
isNewLayout(element);
data.add(element);
notifyItemInserted(data.size());
compatibilityDataSizeChanged(1);
}
/**
* 在指定位置添加一个item,如果position越界则添加到列表最后
* @param position item添加的位置
* @param element item的数据
*/
public void addNewItem(@IntRange(from = 0) int position,@NonNull T element) {
if (position < data.size()){
isNewLayout(element);
data.add(position, element);
//更新数据集用notifyItemInserted(position)与notifyItemRemoved(position) 否则没有动画效果。
//首个Item位置做增加操作
notifyItemInserted(position);
compatibilityDataSizeChanged(1);
}else {
addNewItem(element);
}
}
/**
* 在指定位置添加多个item,如果position越界则添加到列表最后
* 示例:mAdapter.addData(1, listOf(Person("xin","1"),Person("xin","2")))
* @param position 插入位置
* @param newData 多个item的集合
*/
public void addNewData(@IntRange(from = 0) int position, @NonNull Collection extends T> newData) {
if (position < data.size()){
isNewLayout(newData);
data.addAll(position, newData);
notifyItemRangeInserted(position, newData.size());
compatibilityDataSizeChanged(newData.size());
}else {
addNewData(newData);
}
}
/**
* 在列表最后添加多个item
* 示例:mAdapter.addData(listOf(Person("xin","1"),Person("xin","2")))
* @param newData 多个item的集合
*/
public void addNewData(@NonNull Collection extends T> newData) {
isNewLayout(newData);
data.addAll(newData);
notifyItemRangeInserted(data.size() - newData.size() , newData.size());
compatibilityDataSizeChanged(newData.size());
}
/**
* 删除一个指定位置的item,如果position越界则无效
* @param position 指定item的位置
*/
public void removeItem(@IntRange(from = 0) int position) {
if (position < data.size()){
data.remove(position);
notifyItemRemoved(position);
compatibilityDataSizeChanged(0);
notifyItemRangeChanged(position, data.size() - position);
}
}
/**
* 修改某个item的数据,如果position越界则无效
* @param position item位置
* @param element 要修改的item数据
*/
public void replaceItem(@IntRange(from = 0) int position, @NonNull T element) {
if (position < data.size()){
isNewLayout(element);
data.set(position, element);
notifyItemChanged(position);
}
}
/**
* 修改所有item的数据
* @param newData 更新item数据的集合
*/
public void replaceData(@NonNull Collection extends T> newData) {
// 不是同一个引用才清空列表
if (newData != data) {
isNewLayout(newData);
data.clear();
data.addAll(newData);
}
notifyDataSetChanged();
}