对于一个写代码有洁癖、始终重复的写同样而不简洁的代码,是无法忍受的。
一个APP中,RecyclerView和ListView的使用会比较频繁。需要的时候,都会重复的写Adapter。这样使得不够通用,不够简洁。下面就针对RecyclerView.Adapter展开来写。
RecyclerView是由多个item组成的,这里我们可以把每一项item看成一个DataHolder, DataHolder的代码如下:
public abstract class DataHolder {
private Object mData = null;
private int mType;
public DataHolder(Object data, int type){
mData = data;
mType = type;
}
public abstract GenericViewHolder onCreateView(Context context);
public abstract void onBindView(Context context, GenericViewHolder holder, int position, Object data);
public Object getData()
{
return mData;
}
public int getType() {
return mType;
}
}
1.构造函数中两个参数,第一个参数data是一个实体类(界面上需要展示的数据),第二个参数type是item的布局类型(Adapter中可以有多种不同类型的布局)
2.两个抽象方法onCreateView()和onBindView()是不是很眼熟。没错,就是仿照Adapter的onCreateViewHolder()和onBindViewHolder()写的,用法大致相同,前者初始化布局,后者设置数据。
RecyclerView中使用ViewHolder来缓存布局,避免多次实例化,也仿照写了GenericViewHolder,如下:
public class GenericViewHolder extends RecyclerView.ViewHolder {
protected View[] mParams = null;
protected Object mTag = null;
public GenericViewHolder(View itemView,View... params) {
super(itemView);
mParams = params;
}
public void setParams(View... params)
{
mParams = params;
}
public View[] getParams()
{
return mParams;
}
public void setTag(Object tag)
{
mTag = tag;
}
public Object getTag()
{
return mTag;
}
}
1.构造函数中itemView就是onCreateView()中初始化的布局,params就是初始化的控件
2.getParams();获取初始化的控件
最重要的Adapter来了,GenericAdapter继承RecyclerView.Adapter,如下:
public class GenericAdapter extends RecyclerView.Adapter<GenericViewHolder> {
private Context mContext = null;
private List<DataHolder> mHolders = null;
public GenericAdapter(Context context){
mContext = context;
mHolders = new ArrayList<>();
}
public Context getContext(){
return mContext;
}
public void addDataHolder(DataHolder holder)
{
mHolders.add(holder);
// notifyDataSetChanged();
}
public void addDataHolder(int location, DataHolder holder)
{
mHolders.add(location, holder);
notifyDataSetChanged();
}
public void addDataHolders(List<DataHolder> holders)
{
mHolders.addAll(holders);
notifyDataSetChanged();
}
public void addDataHolders(int location, List<DataHolder> holders)
{
mHolders.addAll(location, holders);
notifyDataSetChanged();
}
public void removeDataHolder(int location)
{
mHolders.remove(location);
notifyDataSetChanged();
}
public void removeDataHolder(DataHolder holder)
{
mHolders.remove(holder);
notifyDataSetChanged();
}
public void removeDataHolders(int start){
int size = mHolders.size();
if(start >=0 && start < size){
while(start < size){
mHolders.remove(size - 1);
size = mHolders.size();
}
}
notifyDataSetChanged();
}
public void clearDataHolders(boolean isNotify){
mHolders.clear();
if(isNotify)notifyDataSetChanged();
}
public List<DataHolder> getData(){
return mHolders;
}
/**
* 根据布局类型查DataHolder
* @param viewType
* @return
*/
public DataHolder queryDataHolder(int viewType)
{
int size = mHolders.size();
for(int i = 0 ; i < size;i++){
DataHolder holder = mHolders.get(i);
if(viewType == holder.getType()){
return holder;
}
}
return null;
}
@Override
public GenericViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
DataHolder holder = queryDataHolder(viewType);
return holder.onCreateView(mContext);
}
@Override
public final void onBindViewHolder(GenericViewHolder viewHolder, int position) {
DataHolder holder = mHolders.get(position);
holder.onBindView(mContext,viewHolder,position,holder.getData());
}
@Override
public final int getItemCount() {
return mHolders.size();
}
@Override
public int getItemViewType(int position) {
return mHolders.get(position).getType();
}
@Override
public final long getItemId(int position) {
return super.getItemId(position);
}
}
1.重写onCreateViewHolder,该方法中调用了queryDataHolder()方法,此方法是根据布局类型,找出对应该类型的DataHolder;找到对应的DataHolder后,在调用不同类型布局的onCreateView(),分别进行实例化。
2.重写onBindViewHolder,该方法会执行DataHolder中的onBindView(),用来设置数据
3.addDataHolder()方法,向Adapter中添加item
4.addDataHolders()方法,向Adapter中添加数据集的item
demo地址:https://github.com/SimpleWei00/GenericAdapter