通用Adapter的尝试

本文深入探讨了通用Adapter的设计与实现,包括针对ListView、GridView、RecycleView和ViewPager的兼容性,通过ViewHolder优化代码结构,简化Adapter的编写,并提供通用Adapter的代码实现,以及如何在实际项目中应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


转载请标明出处:http://blog.youkuaiyun.com/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 .


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值