一·创建RecyclerAdapter的java文件
import android.annotation.SuppressLint;
import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.zyf.italker.common.R;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import butterknife.ButterKnife;//需引入Butterknife,自行百度,如不想则将@Bind全部替换为普通findViewById
import butterknife.Unbinder;
public abstract class RecyclerAdapter<Data> extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder<Data>>
implements View.OnClickListener, View.OnLongClickListener, AdapterCallback<Data> {
private final List<Data> mDataList;
private AdapterListener<Data> mListener;
/**
* 构造函数模块
* */
public RecyclerAdapter() {
this(null);
}
public RecyclerAdapter(AdapterListener<Data> listener) {
this(new ArrayList<Data>(), listener);
}
public RecyclerAdapter(List<Data> dataList, AdapterListener<Data> listener) {
this.mDataList = dataList;
this.mListener = listener;
}
/*
* 复写默认的布局类型返回
* @param position 坐标
* @return 类型,其实复写后返回的都是XML文件的ID
* */
@Override
public int getItemViewType(int position) {
return getItemViewType(position, mDataList.get(position));
}
/**
* 得到布局的类型
* @param position 坐标
* @param data 当前的数据
* @return XML文件的ID,用于创建ViewHolder
*/
@LayoutRes
protected abstract int getItemViewType(int position, Data data);
/**
*创建一个ViewHolder
* @param parent RecyclerView
* @param viewType 界面的类型,约定为XML布局的id
* @return ViewHolder
* */
@SuppressLint("InvalidRUsage")
@NonNull
@Override
public ViewHolder<Data> onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
//得到LayoutInflater用于把XML初始化为View
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
//把XML id为viewType的文件初始化为一个 root View
View root = inflater.inflate(viewType, parent, false);
//通过子类必须实现的方法,得到一个ViewHolder
ViewHolder<Data> holder = onCreatViewHolder(root, viewType);
//设置事件点击
root.setOnClickListener(this);
root.setOnLongClickListener(this);
//设置View的Tag为ViewHolder,进行双向绑定
root.setTag(R.id.tag_recycler_holder, holder);
//进行界面注解的绑定
holder.unbinder = ButterKnife.bind(holder, root);
//绑定callback
holder.callback = this;
return holder;
}
/**
得到一个新的ViewHolder
*@param root 根布局
*@param viewType 布局类型,其实就是XML的ID
*@return ViewHolder
* */
protected abstract ViewHolder<Data> onCreatViewHolder(View root, int viewType);
/**
* 绑定数据到一个Holder上
* @param holder ViewHolder
* @param position 坐标
*/
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
//得到需要绑定的数据
Data data = mDataList.get(position);
//出发Holder的绑定方法
holder.bind(data);
}
/**
* 得到当前集合的数据量
**/
@Override
public int getItemCount() {
return mDataList.size();
}
/**
* 返回整个集合
*
* @return List<Data>
*/
public List<Data> getItems() {
return mDataList;
}
/*插入一条数据并通知插入*/
public void add(Data data) {
mDataList.add(data);
notifyItemInserted(mDataList.size() - 1);
}
/*插入一堆数据并通知这段集合更新*/
public void add(Data... dataList) {
if (dataList != null && dataList.length > 0) {
int startPos = mDataList.size();
Collections.addAll(mDataList, dataList);
notifyItemRangeInserted(startPos, dataList.length);
}
}
/*插入一堆数据并通知这段集合更新*/
public void add(Collection<Data> dataList) {
if (dataList != null && dataList.size() > 0) {
int startPos = mDataList.size();
mDataList.addAll(dataList);
notifyItemRangeInserted(startPos, dataList.size());
}
}
/*
* 删除操作
* */
public void clear() {
mDataList.clear();
notifyDataSetChanged();
}
/*
* 替换为一个新的集合,其中包括了清空
* @param dataList 一个新的集合
* */
public void replace(Collection<Data> dataList) {
mDataList.clear();
if (dataList == null || dataList.size() == 0)
return;
mDataList.addAll(dataList);
notifyDataSetChanged();
}
@Override
public void update(Data data, ViewHolder<Data> holder) {
//得到当前ViewHolder的坐标
int pos = holder.getAdapterPosition();
if(pos>=0){
//进行数据的移除与更新
mDataList.remove(pos);
mDataList.add(pos,data);
//通知这个坐标下的数据有更新
notifyItemChanged(pos);
}
}
@Override
public void onClick(View view) {
@SuppressLint("InvalidRUsage")
ViewHolder viewHolder = (ViewHolder) view.getTag(R.id.tag_recycler_holder);
if (this.mListener != null) {
//得到ViewHolder当前对应的适配器坐标
int pos = viewHolder.getAdapterPosition();
//回调方法
this.mListener.onItemClick(viewHolder, mDataList.get(pos));
}
}
@Override
public boolean onLongClick(View view) {
@SuppressLint("InvalidRUsage")
ViewHolder viewHolder = (ViewHolder) view.getTag(R.id.tag_recycler_holder);
if (this.mListener != null) {
//得到ViewHolder当前对应的适配器坐标
int pos = viewHolder.getAdapterPosition();
//回调方法
this.mListener.onItemLongClick(viewHolder, mDataList.get(pos));
return true;
}
return false;
}
/*
* 设置适配器监听
* */
public void setListener(AdapterListener<Data> adapterListener) {
this.mListener = adapterListener;
}
/*
* 我们的自定义监听器
* @param <Data>泛型
* */
public interface AdapterListener<Data> {
//当Cell点击的时候触发
void onItemClick(RecyclerAdapter.ViewHolder holder, Data data);
//当Cell长按的时候触发
void onItemLongClick(RecyclerAdapter.ViewHolder holder, Data data);
}
/*
* 自定义的ViewHolder
* @param<Data>泛型类型
* */
public static abstract class ViewHolder<Data> extends RecyclerView.ViewHolder {
private Unbinder unbinder;
private AdapterCallback callback;
protected Data mData;
public ViewHolder(View itemView) {
super(itemView);
}
/**
* 用于绑定数据的触发
*
* @param data 绑定的数据
*/
void bind(Data data) {
this.mData = data;
onBind(data);
}
/*
* 当触发绑定数据时的回调,必须复写。
* @param data 绑定的数据
*
*/
protected abstract void onBind(Data data);
/*
Holder自己对自己对应的data进行更新操作
*/
public void updateData(Data data) {
if (this.callback != null) {
this.callback.update(data, this);
}
}
}
/**
*对回掉接口做一次实现
* @param <Data>
*/
public static abstract class AdapterListenerImpl<Data> implements AdapterListener<Data>{
@Override
public void onItemClick(ViewHolder holder, Data data) {
}
@Override
public void onItemLongClick(ViewHolder holder, Data data) {
}
}
}
二·同目录下创建java文件AdapterCallback
public interface AdapterCallback<Data> {
void update(Data data, RecyclerAdapter.ViewHolder<Data>holder);
}