转载请注明出处:http://blog.csdn.net/mr_liabill/article/details/48372265 来自《LiaBin的博客》
面试的时候这个问题经常会被问到,稍微总结一下
主要是Adapter的优化
1. 使用缓存的item,而不是每次都new
利用ListView自身的缓存机制,他会缓存条目中的一个条目item,当listview第一屏显示完成之后,就会出现一个缓存条目,其实就是BaseAdapter里面的public View getView(int position,View convertView, ViewGroup parent)
2. 使用ViewHolder,配合getTag,setTag
减少findViewById()的次数,findViewById是一个相对比较耗性能的操作,因为这个操作每次都需要到布局中去查找文件。可以使用ViewHolder,配合setTag,getTag使用,listview中viewholder不是必须的,同时需要配合getTag,setTag使用,但是在RecycleView中ViewHolder中却是必须的,这也是推荐使用RecyclerView代替ListView的原因之一
3. 加载图片优化
这个可以从以下两方面讲
1 加载本地大图
2 listview滚动的时候管理图片内存
参考 http://blog.csdn.net/mr_liabill/article/details/48371929 这篇文章
4. Item如果需要绑定事件处理器,不能在getView中绑定,新建一个事件处理器对象,配合getTag,setTag使用
这点很多人都会不小心忽略,直接上代码,代码中解释
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.item, null);
holder = new ViewHolder();
holder.view = (View)convertView.findViewById(R.id.text);
convertView.setTag(holder);
} else {
holder = (ViewHolder)convertView.getTag();
}
holder.view.set(mData.get(position));
holder.view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//handle click event.........
}
});
return convertView;
}
public static class ViewHolder {
public View view;
}
很多人喜欢这样做,把事件处理放在getview中,殊不知这样就会创建多个匿名内部对象,想想看如果一屏内有20项item,那么便有20个匿名View.OnClickListener,,,,
解决方案如下
private View.OnClickListener onClickListener = new View.OnClickListener(){
@Override
public void onClick(View v) {
//取出view对应的数据项
Data data= v.getTag();
//do some thing........
}
};
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.item, null);
holder = new ViewHolder();
holder.view = (View)convertView.findViewById(R.id.text);
convertView.setTag(holder);
} else {
holder = (ViewHolder)convertView.getTag();
}
holder.view.setXXX(mData.get(position));
//数据项和view绑定
holder.view.setTag(mData.get(position));
return convertView;
}
public static class ViewHolder {
public View view;
}
这样不就只有一个View.OnClickListener对象,避免多个匿名内部对象
6. 未完待续