baseadapter的二次封装

3 篇文章 0 订阅
1 篇文章 0 订阅

首先要对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

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值