你的位置:首页 > 操作系统

[操作系统]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<T> extends BaseAdapter {  /**   * 上下文   */  private Context mContext;  /**   * 实体类集合   */  private List<T> mDatas;  private LayoutInflater mInflater;  /**   * 控件id   */  private int mlayoutId;  public CommonAdapter(Context context, List<T> 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<View> 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<View>();    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 <T 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<Bean> {  public MyAdapter(Context context, List<Bean> 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<Bean> 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 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布局:

<?

效果图:


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<Map<String, String>> lists = new ArrayList<Map<String, String>>();  @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<String, String>();      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:

<?

效果图:

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