自定义封装了ViewHolder的BaseAdapter,简化了Adapter的编写

自定义封装了ViewHolder的BaseAdapter,简化了Adapter的编写

有过一定开发经验的Android程序员一定知道保持View对象的引用在提高ListView的性能上很有帮助,所以每次实现BaseAdapter的子类都要写个ViewHolder。如下:

  @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        //每次都要判断convertView是否存在,这样写其实很繁琐
        ViewHolder viewHolder=null;
        if (convertView==null){
            convertView=inflater.inflate(R.layout.item_layout,parent,false);
            viewHolder=new ViewHolder(convertView);
            convertView.setTag(viewHolder);
        }else{
            viewHolder= (ViewHolder) convertView.getTag();
        }
        Data data=list.get(position);
        //
        viewHolder.textView1.setText(data.getName());
        //
        viewHolder.textView2.setText(data.getSex());


    /**
     * 适配器的引用
     */
    private static class ViewHolder{
        public  TextView textView1; 
        public  TextView textView2;
        }
    }

所以我就想了,为何不利用面向对象的思想把这份重复编写的代码给封装起来,
因为在每个Adapter的getView方法里,其主要流程是一样的:
1.判断convertView是否为空,如果convertView为空,则进行步骤2,否则进行步骤4;
2.创建一个新的view赋值给convertView;
3.为这个convertView创建一个新的ViewHolder,并设置该ViewHolder为convertView的标签;
4.获得ViewHolder,根据业务的不同使用ViewHolder里的控件引用。

其实,这些个步骤组合在一起,相当于一个模板!任何Adapter的getView()方法里都会遵循这个模板流程去执行,只是,不同的Adapter根据业务的不同,以下步骤会有所不同:步骤2,步骤3,步骤4。
这个问题是不是很熟悉,对于完成一个任务,有一样的模板,而子步骤的实现可能不一样,解决这一类的问题,通常我们可以使用"模板模式"——又叫"模板方法模式",在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中。模板方法使得子类可以在不改变算法结构的情冴下,重新定义算法中的某些步骤。
在这个问题里,笔者同样采用了模板模式的思想,定义了一个 BaseMyAdapter 作为模板(抽象)类:
/**
 * 封装了ViewHolder的Adapter
 * Created by tzy on 2015/8/13.
 */
public abstract class BaseMyAdapter extends BaseAdapter {

    public BaseMyAdapter() {}

    @Override
    public int getCount() {
        return list.size();
    }

    @Override
    public T getItem(int position) {
        return null;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    public static class ViewHolder {}//这个ViewHolder 主要是用来继承的

    //这里是模板方法,定义了获取View的算法骨架
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        //在这里BaseMyAdapter做了convertView是否复用的判断
        ViewHolder viewHolder; 
        if(convertView == null)  
        {   //如果convertView 还是空的,则生成一个新的View
            convertView = createView(position, convertView, parent);
            //要根据convertView来获取ViewHolder对象
            viewHolder = getViewHolder(convertView);
            //将
            convertView.setTag(viewHolder);
        }

        else
        {
            viewHolder = (ViewHolder) convertView.getTag();
        }

        loadData(viewHolder, position, convertView, parent);
        return convertView;
    }


    /**
     *获得ViewHolde。抽象行为,放到子类去实现
     * @param v
     * @return
     */
    public  abstract  ViewHolder getViewHolder(View v);

    /**
     *获得View。抽象行为,放到子类去实现
     * @param position
     * @param convertView
     * @param parent
     * @return
     */
    public abstract  View createView(int position, View convertView, ViewGroup parent);

    /**
     *加载数据。抽象行为,放到子类去实现
     * @param viewHolder
     * @param position
     * @param convertView
     * @param parent
     */
    public  abstract  void loadData(ViewHolder viewHolder,int position, View convertView, ViewGroup parent);
}

然后接下来是这个模板的一个具体类:

/**
 * 具体的Adapter
 * Created by tzy on 2015/8/18.
 */
public class ConcreteAdapter  extends  BaseMyAdapter<OrderDetail.OList>{

    public ConcreteAdapter  () {
        super();
    }
    //实现抽象类的方法
    @Override
    public ViewHolder getViewHolder(View v) {

        MyViewHolder viewHolder =new MyViewHolder();
        viewHolder.textPrice =(TextView)v.findViewById(R.id.textSubtotal);
        viewHolder.textZone =(TextView)v.findViewById(R.id.textZone);
        return viewHolder;
    }

    //实现抽象类的方法
    @Override
    public View createView(int position, View convertView, ViewGroup parent) {
        return inflater.inflate(R.layout.item_olist,null,false);
    }

    //实现抽象类的方法
    @Override
    public void loadData(ViewHolder viewHolder, int position, View convertView, ViewGroup parent) {
        OrderDetail.OList data = list.get(position);

        MyViewHolder myViewHolder = (MyViewHolder) viewHolder;
        myViewHolder.textPrice.setText("¥"+data.getSubtotal());
        myViewHolder.textZone.setText(data.getZone());
    }

    //实现的ViewHolder
    class MyViewHolder extends  ViewHolder
    {
        public TextView textZone;
        public TextView textPrice;
    }

}

看吧,这样的具体的一个Adapter就很简洁了,之前写在一起的几个步骤,现在分散到子类的这些方法去实现了。子类只需要实现这些方法,就可以获取到view了,而不用在重复地写那些判断逻辑了,因为这些工作模板类已经帮我们做了!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值