您的位置:首页 > 移动开发 > Android开发

通用Adapter的尝试

2016-05-09 19:22 429 查看



转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/38902805 ,本文出自【张鸿洋的博客】

注:本文内容基本基于鸿洋大神的博客,地址在上面,可以自行阅读。

1.通用Adapter(针对ListView,GridView)

由于作者水平有限,参考大神的博客,自己试着写了写,目前运用在listview和gridview中,对于recycleView和Viewpager的兼容还是不行的,不过大神博客里上传到Git上的那个版本是支持recycleview的,至于viewpager,个人观点,应该可以整合到一起,就会变成一个全通用的Adapter了。之所以这么说是因为之前尝试过一次,公用一个adapter,实现baseadapter,继承pageradapter,所有需要重写的方法都重写,当时只能过做到简单的显示,后来就放在一边就没继续研究,之后有时间会尝试写一写。

2.代码

具体的内容大神的博客里已经将的很详细了,而且对于经常写adapter的人来说阅读起来并不费劲,我就把我自己写过的总体贴一下,有问题欢迎指出。

public class ViewHolder extends RecyclerView.ViewHolder{
private final SparseArray<View> mViews;
private View mConvertView;
private int mPosition;
private int mlayoutId;
private Context mContext;
private ViewHolder(Context context,View itemView,ViewGroup parent,int position){
super(itemView);
mContext=context;
mConvertView=itemView;
mPosition=position;
mViews=new SparseArray<View>();
mConvertView.setTag(this);
}
//获得ViweHolder对象
public static ViewHolder get(Context context,View convertView,ViewGroup parent,int layoutID,int position){
if(convertView==null){
View itemView=LayoutInflater.from(context).inflate(layoutID, parent,false);
ViewHolder viewHolder = new ViewHolder(context, itemView, parent, position);
viewHolder.mlayoutId=layoutID;
return viewHolder;
}else{
ViewHolder holder = (ViewHolder) convertView.getTag();
holder.mPosition=position;
return holder;
}
}
public <T extends View> T getView(int viewId){
View view=mViews.get(viewId);
if(view==null){
view=mConvertView.findViewById(viewId);
mViews.put(viewId, view);
}
return (T)view;
}
public View getConvertView(){
return mConvertView;
}
//设置各种辅助方法
public ViewHolder setText(int viewId,String text){
TextView view=getView(viewId);
view.setText(text);
return this;
}
public ViewHolder setImageResource(int viewId,int drawableId){
ImageView view=getView(viewId);
view.setImageResource(drawableId);
return this;
}
public ViewHolder setImageBitmap(int viewId,Bitmap bitmap){
ImageView view=getView(viewId);
view.setImageBitmap(bitmap);
return this;
}
}
这次代码中基本没有注释,因为并不难,我写的是参照大神在git上的最新的支持recycleview的版本的,可能跟大神博客里的有些不一样,不过基本上原理是一样的。

关于写通用的adapter总结看来主要是针对这几方面:

1.继承basedapter,把一些常用的,基本没有改变的东西都先写好。主要的技巧就是用到了一个泛型,解决了list集合中不同对象的困扰。

2.ViewHolder的写法,大神的博客中也说得很详细了,利用一个SparseArray来保存view对象,SparseArray大家可以把它看做是一个Map,只不过key只能是integer,实际上那SparseArray底层的实现方式是双数组,跟我们平时遇到的都有点不一样,它是一个数组存放key,一个数组存放Value。贴一下源码。

<span style="font-size:18px;">public class SparseArray<E> implements Cloneable {
private static final Object DELETED = new Object();
private boolean mGarbage = false;

private int[] mKeys;
private Object[] mValues;
private int mSize;

/**
* Creates a new SparseArray containing no mappings.
*/
public SparseArray() {
this(10);
}

/**
* Creates a new SparseArray containing no mappings that will not
* require any additional memory allocation to store the specified
* number of mappings.
*/
public SparseArray(int initialCapacity) {
initialCapacity = ArrayUtils.idealIntArraySize(initialCapacity);

mKeys = new int[initialCapacity];
mValues = new Object[initialCapacity];
mSize = 0;
}</span>
可以看出来,是双数组结构,这样更便于查找,至于其他的增删改查方面的大家可以自行去看一下,个人感觉跟arraylist的实现差不多。

3.ViewHolder中对于各种控件属性的赋值方法,个人感觉能够想到这一点的人真是太聪明了,真不知道最开始是怎么想到的。在ViewHolder中封装了大部分常用控件的设置方法,这样真的就是把adapter精简到极致了,写一个adapter只需要一句话。

4.viewholder中对于监听器的设置,这是在大神发在git上的最新的holder中看到的,封装了三个常用的ontouch,onclick,onlongclick方法,可以直接调用。

5.在大神的文档中还有这样的两个东西MultiItemCommonAdapter和MultiItemTypeSupport,这个是用来处理不同itemType的时候使用的,最常见的就是聊天界面左右不同的item了。大家可以自行参考。

3.总结

记得第一次看大神这个文章的时候感觉,**,居然还可以这样?再一看是2014年的文章。顿时感觉自己要努力的地方还有很多啊!准备下一篇写一写关于RecycleView的文章,看到大家现在都用这个,准备研究研究,对于CommonAdapter,个人感觉能简化的就这么多了,也会尝试一下和pageradapter整合,不过现在都是viewpager结合fragment用,适配器也采用的是FragmentPageAdapter,这个整合难度有点大,不过个人认为是可行了,因为需要的方法是不同的,也不相互干扰,应该没问题。还是贴一下CommonAdapter的代码吧。自己也再看一遍。嗯嗯。

public  abstract class CommonAdapter<T> extends BaseAdapter{
protected LayoutInflater mInflater;
protected Context mContext;
protected List<T> mDatas;
protected int layoutID;
public CommonAdapter(Context context,List<T> mDatas,int layoutID){
mInflater=LayoutInflater.from(context);
this.mContext=context;
this.mDatas=mDatas;
this.layoutID=layoutID;
}
@Override
public int getCount() {
return mDatas.size();
}

@Override
public T getItem(int position) {
// TODO Auto-generated method stub
return mDatas.get(position);
}

@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder=ViewHolder.get(mContext, convertView, parent, layoutID, position);
convert(viewHolder,getItem(position));
return viewHolder.getConvertView();
}
public abstract void convert(ViewHolder viewHolder, T item) ;

}


基本上就是常用的方法,不同的就是泛型和getView(),并不难。

文尾附上大神的项目,发表在Git上的,有兴趣的可以下下来看看,或者留邮箱。关于recycleView,百度recycleview jar 包,有很多。(刚试了下自己写的,炸了,一直在报NoClassDefFounfError 错误,不报错误就是一直在deBug,啊啊啊,要命了。)刚尝试下 去掉RecycleView的继承关系就可以了。看来recycleview使用还是有很多需要学的啊。

添加了多种Item类型的支持,源码地址:https://github.com/hongyangAndroid/base-adapter .
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  android adapter 通用