第一版: ListView一屏顯示多少對象其內部就創建多少View對象。滑動時退出的緩存對象留給滑進去時調用getView傳的convertView。因為如果每次都findViewById查找創建視圖對象,浪費性能和記憶體。所以我們都利用佈局創建View給convertView。佈局內部的view對象
第一版:
ListView一屏顯示多少對象其內部就創建多少View對象。滑動時退出的緩存對象留給滑進去時調用getView傳的convertView。因為如果每次都findViewById查找創建視圖對象,浪費性能和記憶體。所以我們都利用佈局創建View給convertView。佈局內部的view對象都事先通過findViewById查找好存到某一個集合對象-ViewHolder:視圖持有者上。並把這個ViewHolder對象放到convertView的Tag上,通過getView返回給Adapter。下一屏時這個緩存的View對象就會被傳進來,此時convertView的Tag屬性中有包含了ViewHoler對象-convertView佈局內部的對象。這樣我們直接用ViewHoler中的對象進行處理了。
下麵就是這個版本通用使用方法:
@Override public View getView(int position, View convertView, ViewGroup parent) { ViewHoler holer; if (convertView == null) { //convertView = View.inflate(mActivity, R.layout.list_**, null); holer = new ViewHoler(); holer.iv_New_Image = (ImageView) convertView.findViewById(R.id.iv_New_Image); holer.tv_Content = (TextView) convertView.findViewById(R.id.tv_Content); holer.tv_Date = (TextView) convertView.findViewById(R.id.tv_Date); convertView.setTag(holer); } else { holer = (ViewHoler) convertView.getTag(); } //自行填寫完整 return convertView; } class ViewHoler { public ImageView iv_New_Image; public TextView tv_Content; public TextView tv_Date; }View Code
因為本人懶惰,所以這種findViewById太麻煩了,所以我自己寫了個工具。根據自動生成代碼。 自定生成ViewHoler代碼(當前頁面只播放一次,再次查看ctrl+f5一下)。工具下載鏈接:http://pan.baidu.com/s/1i4tXwvr
第二個版本:
該版本只是對第一個版本上的設計上的改變,將與ViewHoler相關的代碼集中到了ViewHoler身上。getView職責更加明確,邏輯也更加清晰。
@Override public View getView(int position, View convertView, ViewGroup parent) { ViewHoler holer; if (convertView == null) { //convertView = View.inflate(mActivity, R.layout.list_**, null); holer = new ViewHoler(); } else { holer = (ViewHoler) convertView.getTag(); } //自行填寫完整 return convertView; } class ViewHoler { public ImageView iv_New_Image; public TextView tv_Content; public TextView tv_Date; public ViewHoler(View convertView){ this.iv_New_Image = (ImageView) convertView.findViewById(R.id.iv_New_Image); this.tv_Content = (TextView) convertView.findViewById(R.id.tv_Content); this.tv_Date = (TextView) convertView.findViewById(R.id.tv_Date); convertView.setTag(this); } }View Code
工具已經在這個版本上更新了 http://pan.baidu.com/s/1bnVNbPl
第三個版本:
這個版本與前面的版本本質不同,前面都是靜態代碼。這個ViewHoler中想根據資源Id來獲取View。而我們的View存在內部的一個HashMap中,因為HashMap對於查找的時間複雜度是O(1)的,並且因為是KeyValue不擔心重覆。返回View類型改為泛型是的獲取對象時上層不需要強轉。
//用法 ViewHolerHelper helper=new ViewHolerHelper(convertView); ImageView view=helper.getView(R.id.iv_New_Image); public class ViewHolerHelper { private HashMap<Integer,View> mViews; View convertView; public ViewHolerHelper(View convertView){ mViews=new HashMap<Integer, View>(); convertView.setTag(this); this.convertView=convertView; } public <T> T getView(Integer R_Id){ View view=null; if(!mViews.containsKey(R_Id)){ view=convertView.findViewById(R_Id); if(view!=null){ mViews.put(R_Id, view); } } else{ view=mViews.get(R_Id); } return (T)view; } }View Code