文章目录
  1. 1. 传统的ListView写法
  2. 2. Adapter优化
    1. 2.0.1. ViewHolder的封装
    2. 2.0.2. Adapter的封装

传统的ListView写法

传统的ListView方法是每个ListView都要一个Adapter,这个Adapter继承BaseAdapter,重写四个方法。在getView()方法中获取各种View然后set。高级一点的写法就是使用ViewHolder缓存已经加载的View,然后再获取。这种写法对于ListView数目较少时比较合适,对于实际项目来说并不合适。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
    ViewHolder viewHolder;
View view;
if (convertView == null) {
view = mInflater.inflate(R.layout.item, null);
viewHolder = new ViewHolder();
viewHolder.tv_title = (TextView) view.findViewById(R.id.tv_title);
viewHolder.tv_content = (TextView) view.findViewById(R.id.tv_content);
viewHolder.tv_time = (TextView) view.findViewById(R.id.tv_time);
viewHolder.tv_phone = (TextView) view.findViewById(R.id.tv_phone);


view.setTag(viewHolder);
} else {
view=convertView;
viewHolder = (ViewHolder) view.getTag();

}
Bean bean = getItem(position);
viewHolder.tv_title.setText(bean.getTitle());
viewHolder.tv_content.setText(bean.getDescribe());
viewHolder.tv_time.setText(bean.getTime());
viewHolder.tv_phone.setText(bean.getPhone());


return view;
}

private class ViewHolder {
TextView tv_title;
TextView tv_content;
TextView tv_time;
TextView tv_phone;
}

Adapter优化

ViewHolder的封装

在通常的写法中,用成员变量来保存View,而在这里采用SparseArray来保存View(SparseArray是android里为这样的Hashmap而专门写的class,目的是提高效率)。代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
private SparseArray<View> mViews;
private int position;
private View mConvertView;

public ViewHolder(Context context, ViewGroup parent, int layoutId, int position) {
this.position = position;
this.mViews = new SparseArray<>();
mConvertView = LayoutInflater.from(context).inflate(layoutId, parent, false);
mConvertView.setTag(this);

}
/*
*提供入口方法
*/

public static ViewHolder get(Context context, View convertView,
ViewGroup parent, int position, int layoutId)
{

if (convertView == null) {
return new ViewHolder(context, parent, layoutId, position);
} else {
ViewHolder holder = (ViewHolder) convertView.getTag();
holder.position = position;
return holder;
}

}

/**
* 通过viewId获取控件
*返回一个View的子类
* @return
*/

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;

}

public View getConvertView() {
return mConvertView;
}

public ViewHolder setText(int viewId, String text) {
TextView tv = getView(viewId);
tv.setText(text);
return this;
}

Adapter的封装

创建抽象类CommonAdapter,使其继承BaseAdapter,重写四个方法。在重写getView()方法的时候,就可以使用ViewHolder.get()这个入口方法了。最后创建抽象方法convert(),参数分别为ViewHolder和T,第一个参数旨在让用户取得ViewHolder对象来调用其方法;第二个参数为泛型T,指定Java Bean的类型。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public abstract class CommonAdapter<T> extends BaseAdapter {
//使用protected使子类能够访问
protected List<T> mList;
protected Context mContext;
protected LayoutInflater mInflater;

public CommonAdapter(Context context, List<T> mList) {
this.mList = mList;
this.mContext = context;
mInflater = LayoutInflater.from(context);
}

@Override
public int getCount() {
return mList.size();
}

@Override
public T getItem(int position) {
return mList.get(position);
}

@Override
public long getItemId(int position) {
return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {

ViewHolder holder = ViewHolder.get(mContext, convertView, parent, position, R.layout.item);
convert(holder, getItem(position));
return holder.getConvertView();
}

public abstract void convert(ViewHolder holder, T t);
}

以上通过对ViewHolder和Adapter的封装,是的我们在使用ListView的时候变得十分简单:直接继承CommonAdapter重写convert()方法即可。甚至为了简便,可以直接在setAdapter的时候新建内部类,省去了继承CommonAdapter的过程。以后再使用的时候直接复制这些代码即可。

1
2
3
4
5
6
7
8
9
mListView.setAdapter(new CommonAdapter<Bean>(MainActivity.this, mList) {
@Override
public void convert(ViewHolder holder, Bean bean) {
holder.setText(R.id.tv_title, bean.getTitle())
.setText(R.id.tv_content, bean.getDescribe())
.setText(R.id.tv_time, bean.getTime())
.setText(R.id.tv_phone, bean.getPhone());
}
});

文章目录
  1. 1. 传统的ListView写法
  2. 2. Adapter优化
    1. 2.0.1. ViewHolder的封装
    2. 2.0.2. Adapter的封装