背景
超多的地方用到了 RecyclerView,要是每次都 new 一个 RecyclerAdapter, 就显得很麻烦。
so, 封装 Adapter ,让每次使用的时候,只要完成相关布局即可。
BaseBean
所有 Bean 文件都要继承 BaseBean,viewType 的意义是该 bean 文件所对应的布局,通过设置 viewType 来加载不同的布局。
public class BaseBean implements Serializable {
private int viewType = Flag.DefaultData.none;
public int getViewType() {
return viewType;
}
public void setViewType(int viewType) {
this.viewType = viewType;
}
}
BaseViewHolder
公共的ViewHolder,基本不用再变化的文件。
ViewSugar 专门进行数据处理,糖衣炮弹,每次只要包装他就可以了。
public class BaseViewHolder extends RecyclerView.ViewHolder {
private View itemView;
protected Context context;
public BaseViewHolder(Context context, View itemView) {
super(itemView);
ButterKnife.bind(this, itemView);
this.itemView = itemView;
this.context = context;
}
public View getItemView() {
return itemView;
}
public static BaseViewHolder createViewHolder(Context context, View itemView) {
return new BaseViewHolder(context, itemView);
}
public static BaseViewHolder createViewHolder(Context context,
ViewGroup parent, int layoutId) {
View itemView = LayoutInflater.from(context).inflate(layoutId, parent,
false);
return new BaseViewHolder(context, itemView);
}
public void setTag(ViewSugar viewItem) {
// 设置 tag 文件,不能直接设置 tag,需要设置相应的 key,才不会造成冲突
itemView.setTag(R.integer.sugar, viewItem);
}
public ViewSugar getTag() {
Object tag = itemView.getTag(R.integer.sugar);
if (tag != null
&& tag instanceof ViewSugar) {
return (ViewSugar) tag;
}
return null;
}
}
不同布局,都要创建一个实现类来继承 ViewSugar 。
getLayoutId() 方法,用于返回该布局的 layoutId,bind()方法用来处理数据。
public abstract class ViewSugar {
protected Context context;
protected ViewGroup parent;
protected BaseViewHolder baseViewHolder;
protected View rootView;
public ViewSugar(Context context, ViewGroup parent) {
this.context = context;
this.parent = parent;
baseViewHolder = createViewHolder(getLayoutId());
rootView = baseViewHolder.getItemView();
ButterKnife.bind(this, rootView);
}
public abstract @LayoutRes int getLayoutId();
public abstract <T extends BaseBean> void bind(T obj);
private BaseViewHolder createViewHolder(int layoutId) {
return BaseViewHolder.createViewHolder(context, parent, layoutId);
}
public BaseViewHolder getViewHolder() {
baseViewHolder.setTag(this);
return baseViewHolder;
}
}
ViewHolderFactory
这个类根据不同的 itemType 来获取不同的 ViewSugar 相对应的 ViewHolder, 用在 Adapter 的 onCreateViewHolder 方法中。
public class ViewHolderFactory {
public static BaseViewHolder getViewHolder(Context context, ViewGroup parent, int type) {
ViewSugar viewSugar = null;
switch (type) {
case 101:
// 在这里获取 ViewSugar 的实现类
break;
}
if (viewSugar != null) {
return viewSugar.getViewHolder();
}
return null;
}
}
BaseRecyclerAdapter
首先需要创建一个点击监听接口:
public interface OnItemClickListener {
void onItemClicked(int position, Object obj);
boolean onItemLongClicked(int position, Object obj);
}
public class BaseRecyclerAdapter<T extends BaseBean> extends RecyclerView.Adapter<BaseViewHolder> {
protected Context context;
protected List<T> dataList = new ArrayList<>();
private OnItemClickListener onItemClickListener;
public BaseRecyclerAdapter(Context context) {
this.context = context;
}
public void setOnItemClickListener(OnItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
public void init(@NonNull List<T> data) {
this.dataList.clear();
this.dataList.addAll(data);
}
public void clear() {
this.dataList.clear();
}
public void addAll(@NonNull List<T> data) {
this.dataList.addAll(data);
}
public void add(@NonNull T data) {
this.dataList.add(data);
}
public void remove(int i) {
this.dataList.remove(i);
}
public void remove(@NonNull T t) {
if (this.dataList.contains(t)) {
dataList.remove(t);
}
}
public boolean contains(@NonNull T data) {
if (dataList.isEmpty()) {
return false;
} else if (dataList.contains(data)) {
return true;
}
return false;
}
public List<T> getData() {
return dataList;
}
public T getItem(int index) {
if (!dataList.isEmpty() && index >= 0 && index < dataList.size()) {
return dataList.get(index);
} else {
return null;
}
}
public void replaceItemByPos(int pos, T item) {
if (pos < 0 || pos >= dataList.size() || item == null) {
return;
}
dataList.remove(pos);
dataList.add(pos, item);
}
public void replaceItemList(int start, List<T> list) {
if (start >= dataList.size() || list == null || list.isEmpty()) {
return;
}
for (int i = start; i < start + list.size(); i++) {
if (start < dataList.size()) {
dataList.remove(start);
} else {
break;
}
}
if (start >= dataList.size()) {
dataList.addAll(list);
} else {
dataList.addAll(start, list);
}
}
@Override
public int getItemViewType(int position) {
return dataList.get(position).getViewType();
}
@Override
public BaseViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
return ViewHolderFactory.getViewHolder(context, parent, viewType);
}
@Override
public void onBindViewHolder(final BaseViewHolder holder, int position) {
if (holder.getTag() != null) {
ViewSugar viewSugar = holder.getTag();
viewSugar.bind(dataList.get(position));
View itemView = holder.getItemView();
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (onItemClickListener != null) {
onItemClickListener.onItemClicked(
holder.getAdapterPosition()
, dataList.get(holder.getAdapterPosition()));
}
}
});
itemView.setOnLongClickListener(new View.OnLongClickListener() {
@Override
public boolean onLongClick(View v) {
return onItemClickListener != null
&& onItemClickListener.onItemLongClicked(holder.getAdapterPosition()
, dataList.get(holder.getAdapterPosition()));
}
});
}
}
@Override
public int getItemCount() {
return dataList.size();
}
}
举个例子
创建一个 ViewSugar 实现类:
public class ViewHolderWhat extends ViewSugar {
@BindView(R.id.view_item_user_name_tv)
TextView mUserNameTv;
public static ViewSugar getInstance(Context context, ViewGroup parent) {
return new ViewHolderWhat (context, parent);
}
private ViewHolderWhat (Context context, ViewGroup parent) {
super(context, parent);
}
@Override
public int getLayoutId() {
return R.layout.view_item_post_comment;
}
@Override
public <T extends BaseBean> void bind(final T obj) {
if (obj != null && obj instanceof WhatBean ){
WhatBean bean = (WhatBean ) obj;
mUserNameTv.setText(bean.getUserName());
}
}
}
在 ViewHolderFactory 中添加进去:
public class ViewHolderFactory {
public static BaseViewHolder getViewHolder(Context context, ViewGroup parent, int type) {
ViewSugar viewSugar = null;
switch (type) {
case 101:
// 在这里获取 ViewSugar 的实现类
viewSugar = ViewHolderWhat.getInstance(context, parent);
break;
}
if (viewSugar != null) {
return viewSugar.getViewHolder();
}
return null;
}
}
重写 bean 文件的 getViewType() 方法,或者在获取到bean 对象的时候 setViewType()。
public class WhatBean extends BaseBean {
@Override
public int getViewType() {
return 101;
}
}
使用 BaseRecyclerAdapter 加载 这个 WhatBean 即可展示对应的布局。
建议 ViewType 的值声明到一个单独的文件,以方便管理。