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

来源:互联网 发布:阿里云ecs挂载数据盘 编辑:程序博客网 时间:2024/06/08 19:13

自定义封装了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了,而不用在重复地写那些判断逻辑了,因为这些工作模板类已经帮我们做了!

0 0