ListView是Android中一个很重要的控件,好多信息的展示都是通过ListView。在我们使用listView的时候,需要注意的也很多。特别是在数据特别多的时候,就要求我们更加注重对ListView的优化,以提高性能。下面我将自己使用ListView的三个阶段分享给大家。希望给大家借鉴。
为了简单说明问题,我在这将listview显示的内容简单化。
如下图所示:
我们来看下adapter的代码.
阶段一
class MyAdapter extends BaseAdapter{
@Override
public int getCount() {
return mData.size();
}
@Override
public Object getItem(int position) {
return mData.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = mLayoutInflater.inflate(R.layout.viewholder_item,null);
TextView mTextView = (TextView) view.findViewById(R.id.textview);
//下面给TextView设置内容
mTextView.setText(mData.get(position));
return view;
}
}
第一种这样写过一段时间,但是后来当ListView条目增多的时候,就会出现明显地卡顿,于是意识到需要对listview进行优化。
阶段二
class MyAdapter extends BaseAdapter`{
@Override
public int getCount() {
return mData.size();
}
@Override
public Object getItem(int position) {
return mData.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(null == convertView){
convertView = mLayoutInflater.inflate(R.layout.viewholder_item,null);
}
TextView mTextView = (TextView)convertView.findViewById(R.id.textview);
//下面给TextView设置内容
mTextView.setText(mData.get(position));
return convertView;
}
}
基于阶段一,对Listview进行了简单的研究,每当我滑动出现新的条目的时候就会调用getView方法,这样做会导致每次都会重新加载布局。加载布局是个比较耗时的操作,特别是条目较多或者频繁滑动的时候。
于是观察了下getView中存在三个参数,其中有一个convertView参数,通过查资料知道了,这个参数用来对条目的View进行缓存,当我第一次使用的时候convertView==null,当第二次或者多次调用的时候,convertView!= null。这个时候我们就可以将缓存的view利用起来,避免了重复加载布局引起的性能问题。
阶段三
class MyAdapter extends BaseAdapter`{
@Override
public int getCount() {
return mData.size();
}
@Override
public Object getItem(int position) {
return mData.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if(null == convertView){
holder = new ViewHolder();
convertView = mLayoutInflater.inflate(R.layout.viewholder_item,null);
holder.mTextView = (TextView) convertView.findViewById(R.id.textview);
convertView.setTag(holder);
}else{
holder = (ViewHolder) convertView.getTag();
}
//下面给TextView设置内容
holder.mTextView.setText(mData.get(position));
return convertView;
}
private final class ViewHolder{
private TextView mTextView;
}
}
有了第二个阶段,自以为listview使用不过如此,优化也很简单啊。但是细心的就会发现,我们这样做虽然对缓存的convertView进行了重复利用,但是会反复的findViewbyId查找我们需要操作的控件。这个操作也是比较耗时的,特别是在条目比较多的时候。所以第三种方式诞生,通过这种方式我们避免了重复查找条目中的控件,达到性能的进一步提升。