baseadapter的二次封装

来源:互联网 发布:淘宝客怎么看 编辑:程序博客网 时间:2024/05/29 13:21

首先要对java泛型知识有简单的了解。

一般我们写一个listview(虽然现在用recyclerview比较多)的适配器都要继承baseadapter。但是baseadapter有很多重读性的工作。

为了简化这个过程,下面是一段我封装过后adapter的代码:

public class DemoAdapter extends ListHolderAdapter<String , DemoAdapter.ViewHolder>{    public DemoAdapter(Context mContext, List<String> list) {        super(mContext, list);    }    @Override    public View buildConvertView(LayoutInflater layoutInflater) {        return layoutInflater.inflate(R.layout.item_baseadapter , null);    }    @Override    public ViewHolder buildHolder(View convertView) {        ViewHolder holder = new ViewHolder();        holder.tv = (TextView) convertView.findViewById(R.id.name);        return holder;    }    @Override    public void bindViewDatas(ViewHolder holder, String s, final int position) {        if (!TextUtils.isEmpty(s)){            holder.tv.setText(s);        }    }    public static class ViewHolder{        TextView tv;    }}

怎么样简单吗?只是需要定义好item布局和写好控件的findviewbyid还有set数据这些非重复性的语句.

那么是怎么实现的呢我们先来看继承自baseadapter的类:

public abstract class FrameAdapter<T> extends BaseAdapter{    public Context mContext;    public List<T> list;    public LayoutInflater inflater;    public FrameAdapter(Context mContext , List<T> list){        this.list = list;        this.mContext = mContext;        inflater = LayoutInflater.from(mContext);    }    @Override    public int getCount() {        return list == null? null : list.size();    }    @Override    public Object getItem(int position) {        return list == null? null : list.get(position);    }    @Override    public long getItemId(int position) {        return position;    }}

首先我们自定义了一个adapter抽象类集成自baseadapter.但是我们只重写了三个方法,只是没有重写最重要的getview,这是因为getview中的工作有很多是非重复性的工作,看到这里就会有朋友说convertview.gettag和settag那些不也是重复的么.好吧,别着急小伙子...后边有说明

public abstract class ListHolderAdapter<T,H> extends FrameAdapter<T>{    public ListHolderAdapter(Context mContext, List<T> list) {        super(mContext, list);    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        H holder = null;        T t = list.get(position);        if(convertView == null){            convertView = buildConvertView(inflater);            holder = buildHolder(convertView);            convertView.setTag(holder);        }else{            holder = (H) convertView.getTag();        }        bindViewDatas(holder , t , position);        return convertView;    }    /**     * 构建convertview     * @param layoutInflater     * @return     */    public abstract View buildConvertView(LayoutInflater layoutInflater);    /**     * 构建Holder     * @return     */    public abstract H buildHolder(View convertView);    /**     * 绑定数据     * @param holder     * @param t     * @param position     */    public abstract void bindViewDatas(H holder , T t , int position);}


我们来看看这段代码.我们又定义了一个抽象类继承了上边的FrameAdapter.这样我们就不得不重写getview方法,

熟悉baseadapter的同学会发现getview的写法和普通的写法差不多.是的,几乎就一样,只不过我们把设置item的view和设置view的id和绑定数据代码预留成了抽象类.

这时我们再回顾到最上边的代码块你就会发现一切水到渠成.


当然你可以把两个adapter继承方式写成一个adapter.但是就没有这么灵活了,上边的解耦和复用性都是非常强的.因为第一个FrameAdapter完全可以再被继承这样又可以成为别的样式的Adapter,

下面展示合成一个的做法:

public abstract  class TestAdapter<T,H> extends BaseAdapter{    public Context mContext;    public List<T> list;    public LayoutInflater layoutInflater;    public TestAdapter(Context mContext , List<T> list){        this.mContext = mContext;        this.list = list;        layoutInflater = LayoutInflater.from(mContext);    }    @Override    public int getCount() {        return list == null? null:list.size();    }    @Override    public Object getItem(int position) {        return list == null?null:list.get(position);    }    @Override    public long getItemId(int position) {        return position;    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        H holder = null;        if(convertView == null){            convertView = buildConvert(layoutInflater);            holder = buildHolder(convertView);            convertView.setTag(holder);        }else{            holder = (H) convertView.getTag();        }        bindDatas(holder , list.get(position) , position);        return null;    }    public abstract View buildConvert(LayoutInflater layoutInflater);    public abstract H buildHolder(View ConvertView);    public abstract void bindDatas(H holder , T t , int position);}

想要写自己的adapter和文章第一段代码块是一样的.继承TestAdapter就好了.

因为最近想学一些关于框架的一些思想所以多看了一些文章,泛型真的是一个神奇的东西,想要做架构name必须对相对应的代码熟悉,比如我想二次封装一个adapter那就必须对baseadapter的方法了解.还是在于平时多积累.

本文章学习自http://blog.csdn.net/jenly121

若涉及版权,劳烦周知,本文章可删.


原创粉丝点击