当项目当中遇到了很多个页面都要用到列表的时候,我们可能会用到ListView又或者用到RecyclerView,其实不管用到哪个控件来实现,adapter和hodler是必须要用到的,每写一个ListView或者RecyclerView,都要去实现一个adapter和hodler,显然有很多重复的代码,那么能不能把共有的方法抽取出来呢,显然是可以的,ListView的抽取以前写过,地址是: http://blog.csdn.net/ming_147/article/details/62892727,这边文章主要是叙述RecyclerView的抽取。
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了,是不是方便多了。