ListView(一)通用的ViewHolder

通用的Adapter
(一)传统的写法

    package com.example.generaladapter;

import java.util.List;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

public class MyAdapterO extends BaseAdapter {

    private LayoutInflater mInflater;
    private List<Bean> mDatas;
    public MyAdapterO(Context context,List<Bean> datas){
        mInflater=LayoutInflater.from(context);
        mDatas=datas;
    }
    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return mDatas.size();
    }

    @Override
    public Object 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) {
        // TODO Auto-generated method stub]
        Bean bean=(Bean) getItem(position);
        ViewHolder viewHolder=null;
        if(convertView==null){
            convertView=mInflater.inflate(R.layout.item_listview, null);
            viewHolder=new ViewHolder();
            viewHolder.mTitle=(TextView) convertView.findViewById(R.id.id_title);
            viewHolder.mDesc=(TextView) convertView.findViewById(R.id.id_content);
            viewHolder.mTime=(TextView) convertView.findViewById(R.id.id_time);
            viewHolder.mPhone=(TextView) convertView.findViewById(R.id.id_phone);
            convertView.setTag(viewHolder);
        }else{
            viewHolder=(ViewHolder) convertView.getTag();
        }
        viewHolder.mTitle.setText(bean.getTitle());
        viewHolder.mDesc.setText(bean.getContent());
        viewHolder.mTime.setText(bean.getTime());
        viewHolder.mPhone.setText(bean.getPhone());
        return convertView;
    }
    private class ViewHolder{
        TextView mTitle;
        TextView mDesc;
        TextView mTime;
        TextView mPhone;
    }
}

传统的写法中,对应每一种列表项布局,写一个ViewHolder.由于项目中有多种列表项,要写的代码非常多。能不能有简化的方法呢?

下面我们来看看有什么办法来简化代码的编写
(二)ViewHolder的优化分析
在ViewHolder 中编写getView方法,方法原型如下:
View getViewById(int resId);通过 传入的Id获得相应的View组件。

public View getView(int position,View convertView,ViewGroup parent)
{
      ViewHolder holder=...//初始化viewHolder对象
      TextView tv=holder.getViewById(viewId); //调用getView方法获得view对象。
      tv.setText(..);
}

实现getViewById()方法的数据结构是SparseArray,他存储<\int ,object>键值对,效率高于map.int对应资源id,Object对应View组件。

(三)初始化
ViewHolder的初始化方法,public ViewHolder()中,应该实现如下的功能:

        ViewHolder viewHolder=null;
        if(convertView==null){
            convertView=mInflater.inflate(R.layout.item_listview, null);
            viewHolder=new ViewHolder();
            viewHolder.mTitle=(TextView) convertView.findViewById(R.id.id_title);
            viewHolder.mDesc=(TextView) convertView.findViewById(R.id.id_content);
            viewHolder.mTime=(TextView) convertView.findViewById(R.id.id_time);
            viewHolder.mPhone=(TextView) convertView.findViewById(R.id.id_phone);
            convertView.setTag(viewHolder);
        }else{
            viewHolder=(ViewHolder) convertView.getTag();
        }

convertView==null时,创建新的ViewHolder,并初始化他。 ,convertView!=null时,viewHolder=convertView.getTag();

代码修改如下:

public ViewHolder(Context context, ViewGroup parent, int layout,
            int position) {
        // TODO Auto-generated constructor stub
        mPosition = position;
        mViews = new SparseArray<View>();
        mConvertView = LayoutInflater.from(context).inflate(layout, parent,false);
        mConvertView.setTag(this);
    }

    public static ViewHolder get(Context context, View convertView,
            ViewGroup parent, int layout, int position) {
        if (convertView == null) {
            return new ViewHolder(context, parent, layout, position);
        } else {
            ViewHolder holder = (ViewHolder)convertView.getTag();
            holder.mPosition=position;
            return holder;
        }
    }
        public View getConvertView(){
        return mConvertView;
    } 

(四)getViewById()方法,根据viewId返回view

 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;
    }

(五)viewHolder 和BaseAdapter结合
在Adapter的getView()方法中,获得ViewHolder的方法可以缩短为一行

    ViewHolder holder=ViewHolder.get(this.mContext, convertView, parent, R.layout.item_listview, position);

获取TextView控件并赋值,可以写成

((TextView)holder.getView(R.id.id_title)).setText(bean.getTitle());

返回convertView

return holder.getConvertView();

这种写法节约了多少代码呢?假设有10个listView,按照传统的写法,要定义10个ViewHolder类,并且,在getView方法中if(convertView==null),就要对viewHolder中的每一个组件使用findViewById(),初始化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值