recyclerView:通用适配器
2017-08-04 本文已影响0人
whstywh
unsplash
背景:为了使项目更加整洁,利于开发,后期管理,需要打造一款通用的recyclerview的适配器,功能要求:满足不同数据内容的适配;数据绑定部分简洁易懂;点击事件和长按事件监听;多条目布局的简单实现。学习于 鸿洋 的为RecyclerView打造通用Adapter 让RecyclerView更加好用这篇博文。
不同数据类型的适配使用泛型;
传入布局id动态填充;
在抽象方法中自定义数据绑定部分;
接口回调事项点击和长按事件;
/**
* Created by whstywh on 2017/7/31.
* GitHub:https://github.com/whstywh
* email:whstywh@gmail.com
* description:通用Adapter
*/
public abstract class CommonRAdapter<T> extends RecyclerView.Adapter<CommonRAdapter.CommonViewHolder> {
protected Context mContext;
protected List<T> mList;
protected int mLayoutId;
protected LayoutInflater mLayoutInflater;
public OnItemClickListener mItemClickListener;
public OnLongClickListener mLongClickListener;
public CommonRAdapter(Context context, List<T> list, int layoutId) {
this.mContext = context;
this.mList = list;
this.mLayoutId = layoutId;
mLayoutInflater = LayoutInflater.from(mContext);
}
@Override
public CommonViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = mLayoutInflater.inflate(mLayoutId, parent, false);
CommonViewHolder holder = new CommonViewHolder(view, mContext);
return holder;
}
@Override
public void onBindViewHolder(CommonRAdapter.CommonViewHolder holder, int position) {
convert(holder, mList.get(position));
}
public abstract void convert(CommonViewHolder holder, T itemData);
@Override
public int getItemCount() {
return mList.size();
}
public interface OnItemClickListener {
void itemClick();
}
public interface OnLongClickListener {
boolean longClick();
}
public void setOnItemClickListener(OnItemClickListener itemClickListener) {
this.mItemClickListener = itemClickListener;
}
public void setOnLongClickListener(OnLongClickListener longClickListener) {
this.mLongClickListener = longClickListener;
}
}
使用SparseArray稀疏数组缓存view:因为SparseArray也是通过键值对储存,相比map集合有着占用内存小的优点,用来替代Map<Integer,Objecty>;
通过传入item中的viewId来获取view:如果数组中没有,则findViewById并且缓存至数组中,方便下次获取;
由于item的布局大多为TextView,ImageView,所以封装统一的set(),get()方法;
/***
* ViewHolder
*/
public class CommonViewHolder extends RecyclerView.ViewHolder {
private SparseArray<View> mSparseArray;
public CommonViewHolder(View itemView, Context context) {
super(itemView);
mSparseArray = new SparseArray<>();
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mItemClickListener != null) {
mItemClickListener.itemClick();
}
}
});
itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
return mLongClickListener == null ? false : mLongClickListener.longClick();
}
});
}
public CommonViewHolder setText(int viewId, CharSequence charSequence) {
TextView textView = getView(viewId);
textView.setText(charSequence);
return this;
}
public CommonViewHolder setImage(int viewId, CharSequence charSequence) {
ImageView imageView = getView(viewId);
Glide.with(mContext).load(charSequence).into(imageView);
return this;
}
private <T extends View> T getView(int viewId) {
View view = mSparseArray.get(viewId);
if (view == null) {
view = itemView.findViewById(viewId);
mSparseArray.put(viewId, view);
}
return (T) view;
}
}
多布局是通过自己来分配布局来实现的,定义接口并且在实例adapter的时候传入实现对象,
自定义返回的itemType,layoutId;
/**
* Created by whstywh on 2017/7/31.
* GitHub:https://github.com/whstywh
* email:whstywh@gmail.com
* description:通用适配器—多条目布局
*/
public abstract class MultiItemCommonAdapter<T> extends CommonRAdapter<T> {
protected MultiItemTypeSupport<T> mMultiItemTypeSupport;
@Override
public int getItemViewType(int position) {
return mMultiItemTypeSupport.getItemViewType(position, mList.get(position));
}
public MultiItemCommonAdapter(Context context, List<T> list, int layoutId, MultiItemTypeSupport<T> multiTypeSupport) {
super(context, list, layoutId);
this.mMultiItemTypeSupport = multiTypeSupport;
}
@Override
public CommonRAdapter.CommonViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
mLayoutId = mMultiItemTypeSupport.getLayoutId(viewType);
View view = mLayoutInflater.inflate(mLayoutId, parent, false);
CommonViewHolder holder = new CommonViewHolder(view, mContext);
return holder;
}
//接口
public interface MultiItemTypeSupport<T> {
int getLayoutId(int itemType);
int getItemViewType(int position, T t);
}
}