RecyclerView的Adapter是继承于RecyclerView.Adapter<BaseAdapter.ViewHolder>,ViewHolder在这里我是以泛型的形式引入进来,并在BaseAdapter类中具体实现,如下:
public class BaseAdapter extends RecyclerView.Adapter<BaseAdapter.ViewHolder>{ @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { return null; } @Override public void onBindViewHolder(ViewHolder holder, int position) { } @Override public int getItemCount() { return 0; } public static class ViewHolder extends RecyclerView.ViewHolder { public ViewHolder(View itemView) { super(itemView); } } }
好了,具体就这些方法,那么该如何去下手呢,我们可以先分析一下,要实现一个Adapter,我们都需要哪些条件呢?首先数据是必不可少的,一般是以集合的形式传入,这里我们可以从构造方法里传进,集合确定,而类型不能确定,我们可以用D来标识,实例变量携带泛型,记得给类也加上泛型,这里我写了一个空的接口,用来做双向绑定,如下:
public class BaseAdapter<D extends IModel> extends RecyclerView.Adapter<BaseAdapter.ViewHolder> { private List<D> dataList; public BaseAdapter(List<D> dataList) { this.dataList = dataList; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { return null; } @Override public void onBindViewHolder(ViewHolder holder, int position) { } @Override public int getItemCount() { return dataList.size(); } public static class ViewHolder extends RecyclerView.ViewHolder { public ViewHolder(View itemView) { super(itemView); } } }
数据传入了,那么还少什么呢,对,View视图,这里我把BaseAdapter改成了抽象类,并实现获取view的一个抽象方法,并在onCreateViewHolder方法里进行使用,如下:
public abstract int getLayoutId(); @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(getLayoutId(),parent,false); BaseAdapter.ViewHolder vh = new BaseAdapter.ViewHolder(view); return vh; }
接下来,就是向外继续抽象一个方法,用于数据的绑定,其实就是把onBindViewHolder方法,抽象到外面自己来实现其里面的功能:
public abstract void createHolder(BaseAdapter.ViewHolder holder, D d); @Override public void onBindViewHolder(ViewHolder holder, int position) { createHolder(holder,dataList.get(position)); }
目前为止,adapter里已经抽取完成,下面看下ViewHolder里,其实在ViewHolder里,主要用于获取控件:
public static class ViewHolder extends RecyclerView.ViewHolder { private View rootView; private SparseArray<View> views=new SparseArray<>(); public ViewHolder(View itemView) { super(itemView); } public <T extends View> T get(int id){ T view=(T)views.get(id); if(view==null){ view=(T)rootView.findViewById(id); views.put(id,view); } return view; } //TextView设置数据 public void setText(int viewId, String txt) { TextView mTextView = get(viewId); mTextView.setText(txt); } //设置图片 public void setPic(int viewId, String url) { ImageView mImageView = get(viewId); Picasso.with(mContext).load(url).fit().error(R.drawable.ic_launcher).placeholder(mImageView.getDrawable()).memoryPolicy(MemoryPolicy.NO_CACHE).into(mImageView); } }
这里我写了两个方法setText和setPic,主要目的就是简便我们的代码,方便我们调用,到这里,我们这个BaseAdapter,已经抽取完成了,下面看一下整个类:
/** * Created by AbnerMing on 2017/12/29. */ public abstract class BaseAdapter<D extends IModel> extends RecyclerView.Adapter<BaseAdapter.ViewHolder> { private List<D> dataList; public abstract int getLayoutId(); public BaseAdapter(List<D> dataList) { this.dataList = dataList; } @Override public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(getLayoutId(),parent,false); BaseAdapter.ViewHolder vh = new BaseAdapter.ViewHolder(view); return vh; } @Override public void onBindViewHolder(ViewHolder holder, int position) { createHolder(holder,dataList.get(position)); } @Override public int getItemCount() { return dataList.size(); } public abstract void createHolder(BaseAdapter.ViewHolder holder, D d); public static class ViewHolder extends RecyclerView.ViewHolder { private View rootView; private SparseArray<View> views=new SparseArray<>(); public ViewHolder(View itemView) { super(itemView); } public <T extends View> T get(int id){ T view=(T)views.get(id); if(view==null){ view=(T)rootView.findViewById(id); views.put(id,view); } return view; } //TextView设置数据 public void setText(int viewId, String txt) { TextView mTextView = get(viewId); mTextView.setText(txt); } //设置图片 public void setPic(int viewId, String url) { ImageView mImageView = get(viewId); Picasso.with(mContext).load(url).fit().error(R.drawable.ic_launcher).placeholder(mImageView.getDrawable()).memoryPolicy(MemoryPolicy.NO_CACHE).into(mImageView); } } }
具体调用:
public class MyAdapter extends BaseAdapter<Bean>{ public MyAdapter(List<Bean> dataList) { super(dataList); } @Override public int getLayoutId() { return 0; } @Override public void createHolder(BaseAdapter.ViewHolder holder, Bean bean) { } }
以后所有的Adapter都可以去继承BaseAdapter,只仅仅的实现两个方法就ok了,是不是方便多了。