本人从事android相关的工作也有一年多了的,这段时间也让我成长了不少,在代码的编写上有了很大的提升。这是我第一次写博客,都知道好东西要学会分享,这个通用的listview适配器是我平时开发中经常用到的,在此跟大家交流下,不喜勿喷。如果需要的话,欢迎参考借鉴。
相信很多用过listview的人都有这样子的体验,在开发过程中每次使用adapter都需要做重复的工作,这也很大程度上的影响开发效率。在这里,我整理一个通用的listview适配器,方便以后在使用的过程中简单调用,以此提升开发效率。
1.首先,编写Listview中的item布局文件 — listview_item_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal"
android:padding="10dp">
<ImageView
android:layout_width="60dp"
android:layout_height="60dp"
android:src="@mipmap/ic_launcher" />
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="姓名"
android:textSize="20sp" />
<TextView
android:id="@+id/tv_sex"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingLeft="20dp"
android:text="性别"
android:textSize="20sp" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="right"
android:src="@mipmap/right" />
</LinearLayout>
接着是通用listview适配器类 — BaseCommAdapter
2.创建抽象类BaseCommAdapter继承BaseAdapter,并实现对应方法。同时定义一个构造函数,增加移除数据、添加数据,重置列表等方法以及两个抽象方法,由子类去实现
/**
* Created by chenyk on 2016/6/28.
* 通用adapter
*/
public abstract class BaseCommAdapter<T> extends BaseAdapter {
protected Context mContext;
protected List<T> mListViewDatas;
public BaseCommAdapter(Context context) {
mContext = context;
if (mListViewDatas == null) {
mListViewDatas = new ArrayList<>();
}
}
/**
* 获取所有数据
*
* @return
*/
public List<T> getAllListDatas() {
return mListViewDatas;
}
/**
* 移除指定位置数据
*
* @param position
*/
public T removeData(int position) {
if (position < mListViewDatas.size()) {
T t = mListViewDatas.remove(position);
notifyDataSetChanged();
return t;
}
return null;
}
/**
* 添加数据,从尾部添加
*
* @param listDatas
*/
public void addListDatas2Footer(List<T> listDatas) {
if (listDatas != null) {
mListViewDatas.addAll(listDatas);
notifyDataSetChanged();
}
}
/**
* 添加单个数据,从尾部添加
*
* @param listData
*/
public void addListData2Footer(T listData) {
if (listData != null) {
mListViewDatas.add(listData);
notifyDataSetChanged();
}
}
/**
* 添加数据,从头部添加
*
* @param listDatas
*/
public void addListDatas2Header(List<T> listDatas) {
if (listDatas != null) {
mListViewDatas.addAll(0, listDatas);
notifyDataSetChanged();
}
}
/**
* 重置整个列表的数据
*
* @param listDatas
*/
public void setListDatas(List<T> listDatas) {
mListViewDatas.clear();
if (listDatas != null) {
mListViewDatas.addAll(listDatas);
}
notifyDataSetChanged();
}
@Override
public int getCount() {
return mListViewDatas == null ? 0 : mListViewDatas.size();
}
@Override
public T getItem(int position) {
return mListViewDatas.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder;
if (convertView == null) {
viewHolder = new ViewHolder(mContext, parent, getLVItemViewLayoutID());
convertView = viewHolder.getConvertView();
} else viewHolder = (ViewHolder) convertView.getTag();
T t = getItem(position);
bindView(position, t, viewHolder);
return convertView;
}
protected class ViewHolder {
// 用于存储listView item的容器
private SparseArray<View> mItemViews = new SparseArray<>();
private View mConvertView;
public ViewHolder(Context context, ViewGroup parent, int layoutId) {
this.mConvertView = LayoutInflater.from(context).inflate(layoutId, parent, false);
this.mConvertView.setTag(this);
this.mItemViews = new SparseArray<>();
}
/**
* 获取listView中item对应的view
*
* @return
*/
public View getConvertView() {
return this.mConvertView;
}
/**
* 查找View
*
* @param viewPosition
* @return
*/
public View getView(int viewPosition) {
View view = mItemViews.get(viewPosition);
if (view == null) {
view = mConvertView.findViewById(viewPosition);
mItemViews.put(viewPosition, view);
}
return view;
}
}
/**
* 获取listview中的item布局
*
* @return
*/
public abstract int getLVItemViewLayoutID();
/**
* 将业务数据绑定到具体的 tag上
*
* @param position
* @param data
* @param viewHolder
*/
public abstract void bindView(int position, T data, ViewHolder viewHolder);
}
注意:类中涉及的步骤跟平时用listview适配器基本一致,只不过将传入的bean和item中的view进行了抽离,公共的内容该类已经做出处理,子类只需实现getLVItemViewLayoutID( )和bindView(int position, T data, ViewHolder viewHolder)两个抽象方法即可,获取指定View布局以及进行数据绑定操作
3.创建UserInfoBean类,定义字段Name和sex
/**
* Created by chenyk on 2016/6/28.
* 用户信息
*/
public class UserInfoBean {
private String Name;//姓名
private String sex;//性别
public String getName() {
return Name;
}
public String getSex() {
return sex;
}
public void setName(String name) {
Name = name;
}
public void setSex(String sex) {
this.sex = sex;
}
}
4.创建UserInfoListViewAdapter类并继承BaseCommAdapter,实现抽象方法
/**
* Created by chenyk on 2016/6/28.
* 用户信息列表适配器
*/
public class UserInfoListViewAdapter extends BaseCommAdapter<UserInfoBean> {
public UserInfoListViewAdapter(Context context) {
super(context);
}
@Override
public int getLVItemViewLayoutID() {
return R.layout.listview_item_layout;
}
@Override
public void bindView(int position, UserInfoBean data, ViewHolder viewHolder) {
TextView tvName = (TextView) viewHolder.getView(R.id.tv_name);
TextView tvSex = (TextView) viewHolder.getView(R.id.tv_sex);
tvName.setText(data.getName());
tvSex.setText(data.getSex());
}
}
5.剩下的步骤跟平时对listview的使用过程一样,适配器对象创建并绑定到listview上,添加数据各种事件设置等
mListView = (ListView) findViewById(R.id.my_listview);
mAdapter = new UserInfoListViewAdapter(mActivity);
mListView.setAdapter(mAdapter);
mAdapter.setListDatas(mList);
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
mAdapter.addListData2Footer(mAdapter.getAllListDatas().get(position));
}
});
mListView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
mAdapter.removeData(position);
return true;
}
});
以下是最后的实现效果图: