android万能的Listview适配器

ListView是开发中最常用的控件了,但是总是会写重复的代码,浪费时间又没有意义。

最近参考一些资料,发现一个万能ListView适配器,代码量少,节省时间,总结一下分享给大家。

首先有一个自定义的Adapter继承于BaseAdapter,下面是自定义的Adapter,精华在getView()方法中

package com.example.mylistview.util;import java.util.List;import android.content.Context;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;public abstract class CommonAdapter extends BaseAdapter {    /**     * 上下文     */    private Context mContext;    /**     * 实体类集合     */    private List mDatas;    private LayoutInflater mInflater;    /**     * 控件id     */    private int mlayoutId;    public CommonAdapter(Context context, List datas, int layoutId) {        this.mContext = context;        this.mDatas = datas;        this.mlayoutId = layoutId;        mInflater = LayoutInflater.from(context);    }    @Override    public int getCount() {        // TODO Auto-generated method stub        return mDatas.size();    }    @Override    public T getItem(int arg0) {        // TODO Auto-generated method stub        return mDatas.get(arg0);    }    @Override    public long getItemId(int arg0) {        // TODO Auto-generated method stub        return arg0;    }    @Override    public View getView(int arg0, View arg1, ViewGroup arg2) {        // TODO Auto-generated method stub        ViewHolder holder = ViewHolder.get(mContext, arg1, arg2, mlayoutId,                arg0);        convert(holder, getItem(arg0));        return holder.getConvertView();    }    public abstract void convert(ViewHolder holder, T t);}

以上的抽象方法convert(ViewHolder holder, T t);就相当于以前通用代码中的

viewHolder.mTextView = (TextView) convertView .findViewById(R.id.id_tv_title);

viewHolder.mTextView.setText(Bean.getName());

找到控件的id再去设施setText等重复的代码方法中的参数ViewHolder holder, T t    holder就相当于以前通用代码中的viewHolder,t就相当于一个自己定义的实体类Bean。

以上代码中getView()方法中有一个ViewHolder是需要自己声明的,以下是代码以及详细注释:

package com.example.mylistview.util;import android.content.Context;import android.graphics.Bitmap;import android.renderscript.Type;import android.util.SparseArray;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import android.widget.TextView;public class ViewHolder {    /**     * SparseArray类存放View集合     */    private SparseArray mViews;    /**     *      */    private int mPosition;    /**     * 布局文件     */    private View mConvertView;    public View getConvertView() {        return mConvertView;    }    public ViewHolder(Context context, ViewGroup parent, int layoutId,            int position) {        this.mViews = new SparseArray();        this.mPosition = position;        this.mConvertView = LayoutInflater.from(context).inflate(layoutId,                parent, false);        this.mConvertView.setTag(this);    }    /**     * 拿到一个ViewHolder对象     * @param context     * @param convertView     * @param parent     * @param layoutId     * @param position     * @return     */    public static ViewHolder get(Context context, View convertView,            ViewGroup parent, int layoutId, int position) {        if (null == convertView) {            return new ViewHolder(context, parent, layoutId, position);        } else {            ViewHolder holder = (ViewHolder) convertView.getTag();            holder.mPosition = position;            return holder;        }    }    /**     * 通过控件的id获取对应的控件,如果没有则加入views     * @param viewId     * @return     */    public extends View> T getView(int viewId) {        View view = mViews.get(viewId);        if (null == view) {            view = mConvertView.findViewById(viewId);            mViews.put(viewId, view);        }        return (T) view;    }    /**     * 为TextView设置字符串      * @param viewId     * @param text     * @return     */    public ViewHolder setText(int viewId, String text) {        TextView tv = getView(viewId);        tv.setText(text);        return this;    }    /**      * 为ImageView设置图片      *       * @param viewId      * @param drawableId      * @return      */      public ViewHolder setImageResource(int viewId, int drawableId)      {          ImageView view = getView(viewId);          view.setImageResource(drawableId);          return this;      }          public int getPosition()      {          return mPosition;      }  }

再写一个Adapter继承于万能适配器CommonAdapter,还是要写一个自己的Adapter,因为一个项目可能会有多个ListView,但是每个的item元素,布局都会有所不同的,这个泪用来区分不同的ListView与自己所对应的item.这个代码量较少完全可以写成内部类在Activity.java中.

package com.example.mylistview.adapter;import java.util.List;import android.content.Context;import android.view.View;import android.view.View.OnClickListener;import android.widget.CheckBox;import com.example.mylistview.R;import com.example.mylistview.domain.Bean;import com.example.mylistview.util.CommonAdapter;import com.example.mylistview.util.ViewHolder;public class MyAdapter extends CommonAdapter {    public MyAdapter(Context context, List datas, int layoutId) {        super(context, datas, layoutId);        // TODO Auto-generated constructor stub    }    @Override    public void convert(ViewHolder holder, final Bean bean) {        // TODO Auto-generated method stub        holder.setText(R.id.tv_title, bean.getTitle())                .setText(R.id.tv_desc, bean.getDesc())                .setText(R.id.tv_time, bean.getTime())                .setText(R.id.tv_phone, bean.getPhone());        /**         * 防止CheckBox混乱         */        final CheckBox cBox = (CheckBox)(holder.getView(R.id.cb));        if (cBox != null)        {            cBox.setChecked(bean.isChecked());            cBox.setOnClickListener(new OnClickListener()            {                @Override                public void onClick(View v)                {                    bean.setChecked(cBox.isChecked());                }            });        }    }}

 

优化之后用适配器的时候就简单多了下面是实体类,item和MainActivity.java中的代码:

实体类:

package com.example.mylistview.domain;public class Bean {    private String title;    private String desc;    private String time;    private String phone;    private boolean isChecked;    public boolean isChecked() {        return isChecked;    }    public void setChecked(boolean isChecked) {        this.isChecked = isChecked;    }    /**     * @param title     * @param desc     * @param time     * @param phone     */    public Bean(String title, String desc, String time, String phone) {        this.title = title;        this.desc = desc;        this.time = time;        this.phone = phone;    }    public String getTitle() {        return title;    }    public void setTitle(String title) {        this.title = title;    }    public String getDesc() {        return desc;    }    public void setDesc(String desc) {        this.desc = desc;    }    public String getTime() {        return time;    }    public void setTime(String time) {        this.time = time;    }    public String getPhone() {        return phone;    }    public void setPhone(String phone) {        this.phone = phone;    }}

MainActivity.java:

重点代码:

参数有上下文,集合,和自己对应的item就可以了
 adapter = new MyAdapter(this, mDatas, R.layout.item);
package com.example.mylistview.ui;import java.util.ArrayList;import java.util.List;import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.view.View;import android.widget.AdapterView;import android.widget.AdapterView.OnItemClickListener;import android.widget.ListView;import com.example.mylistview.R;import com.example.mylistview.adapter.MyAdapter;import com.example.mylistview.domain.Bean;public class MainActivity extends Activity {    private ListView listView;    private List mDatas;    /**     * 适配器     */    private MyAdapter adapter;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        initView();        initData();        listener();    }    private void listener() {        // TODO Auto-generated method stub        listView.setOnItemClickListener(new OnItemClickListener() {            @Override            public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,                    long arg3) {                // TODO Auto-generated method stub                startActivity(new Intent(MainActivity.this, SecondActivity.class));            }        });    }    private void initData() {        // TODO Auto-generated method stub        mDatas = new ArrayList();        Bean bean = new Bean("Android新技能 Get",                "Android-打造万能的ListView和GridView适配器", "2015-08-05", "10086");        mDatas.add(bean);        bean = new Bean("捡到权志龙一个",                "在星巴克捡到权志龙一个", "2015-08-06", "10086");        mDatas.add(bean);        bean = new Bean("GetTOP一个",                "在韩国首尔捡到TOP一个", "2015-08-07", "10086");        mDatas.add(bean);            adapter = new MyAdapter(this, mDatas, R.layout.item);        listView.setAdapter(adapter);            }    private void initView() {        // TODO Auto-generated method stub        listView = (ListView) findViewById(R.id.listView);    }}

item布局:

<?xml version="1.0" encoding="utf-8"?>                    

效果图:

用这个去适配另一个不同的布局:

新布局的Adapter一样继承自己的万能adapter:CommonAdapter

package com.example.mylistview.adapter;import java.util.List;import java.util.Map;import android.content.Context;import com.example.mylistview.R;import com.example.mylistview.util.CommonAdapter;import com.example.mylistview.util.ViewHolder;public class SecondAdapter extends CommonAdapter> {    public SecondAdapter(Context context, List> datas,            int layoutId) {        super(context, datas, layoutId);        // TODO Auto-generated constructor stub    }    @Override    public void convert(ViewHolder holder, Map t) {        // TODO Auto-generated method stub        holder.setText(R.id.tv_item2values, t.get("values"));    }}

Activity.java代码:

package com.example.mylistview.ui;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;import android.app.Activity;import android.os.Bundle;import android.widget.ListView;import com.example.mylistview.R;import com.example.mylistview.adapter.MyAdapter;import com.example.mylistview.adapter.SecondAdapter;public class SecondActivity extends Activity {    private ListView listView_second;    private SecondAdapter secondAdapter;    private List> lists = new ArrayList>();    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_second);        initView();        initData();    }    private void initData() {        // TODO Auto-generated method stub        for (int i = 0; i < 4; i++) {            Map map = new HashMap();            map.put("values", "条目" + i);            lists.add(map);        }        secondAdapter = new SecondAdapter(this, lists, R.layout.item2);        listView_second.setAdapter(secondAdapter);    }    private void initView() {        // TODO Auto-generated method stub        listView_second = (ListView) findViewById(R.id.listView_second);    }}

item:

<?xml version="1.0" encoding="utf-8"?>     

效果图:

备忘,希望能给大家带来帮助。