先簡述下使用場景:listview使用的頻率之高簡直貫穿整個android開發,因此對于listview復用的優化在近幾年也是出現了比較多的思路
1,首先是不復用,這個不用說了,直接在adapter的convertview直接寫就好了
2,之后發現不復用的話,數據大的情況下,listview直接造成OOM(內存爆炸),后來出現了if(convertview == null){...}這一種復用
3,再之后就是谷歌爸爸在某一年io大會上推出的viewholder和新的api(settag)(據說是某一位谷歌員工寫來自己玩的,后來給項目老大發現,結果悲劇了)
4,使用了viewholder之后,listview就變得十分流暢,但是出現一個問題就是:如果每一個條目都可以操作(例如:EditText,甚至自己做的一些狀態選擇器,操作之后發現復用的過程中出現問題)。這個在實際的開發過程中,我做出了如下處理:使用一個集合,儲存標記位(boolean類型的flag值),復用的過程中,添加if語句判斷(if(list.get(position).getFlag( ))),根據這個flag進行判斷用戶之前是否操作過該條目---------之后,在閱讀一些技術大牛的博客以及大型項目代碼的過程中,我發現也是很多人這樣處理去避免復用的問題
5,(這個是我閱讀了xiaanming大牛的博客之后,才萌發了強烈的總結listview復用的心理)
public class NewsAdapter extends BaseAdapter {
// 定義Context private
Context mContext;
List<NewsListBean> list = new ArrayList<>();
//定義hashMap 用來存放之前創建的每一項item
HashMap<Integer, View> lmap = new HashMap<Integer, View>();
private ImageLoader imageLoader = ImageLoader.getInstance();
public NewsAdapter(Context context, List<NewsListBean> listViewList) {
this.mContext = context;
this.list = listViewList;
}
@Override
public int getCount() {
return list.size();
}
@Override public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder ViewHolder;
//創建每一個滑動出來的item項,將創建出來的項,放入數組中,為下次復用使用
if (lmap.get(position) == null) {
convertView = LayoutInflater.from(mContext).inflate(R.layout.news_item, null);
ViewHolder = new ViewHolder(convertView);
convertView.setTag(ViewHolder); lmap.put(position,convertView);
} else {
convertView = lmap.get(position);
ViewHolder = (ViewHolder) convertView.getTag();
}
ViewHolder.tv_newstime.setText(list.get(position).getDate());
ViewHolder.tvnewsneirong.setText(list.get(position).getContent());
ViewHolder.tvnewstitle.setText(list.get(position).getTitle());
imageLoader.displayImage(list.get(position).getImg(), ViewHolder.imgnewspic,
Tools.setBeforImageoption());
return convertView;
}
//添加viewHolder
class ViewHolder {
TextView tvnewstitle,newstype,tvnewsneirong,tv_newstime;
ImageView imgnewspic;
public ViewHolder(View convertView) {
tvnewstitle = (TextView) convertView.findViewById(R.id.tvnewtitle);
imgnewspic = (ImageView) convertView.findViewById(R.id.imgnewspic);
newstype= (TextView) convertView.findViewById(R.id.newstype);
tvnewsneirong= (TextView) convertView.findViewById(R.id.tvnewsneirong);
tv_newstime= (TextView) convertView.findViewById(R.id.tv_newstime);
}
}
原理就是,用HashMap<Integer,View>儲存convertView。
代碼還可以優化,狀態也同時放入tag中做保存,同樣在實現復用的時候復用狀態。