Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android ListView 中getview學習總結

android ListView 中getview學習總結

編輯:關於Android編程

最近在做android相關的開發,ListView中有一個圖片錯位的問題,今天查了很多人寫的一些東西,所以記錄下來,算是一種加深理解吧。       ListView是一個非常常用的控件,功能可以擴展的很豐富,而且與GridView有很多相似的地方。都可以存放大量數據。而且當我們需要比較復雜的布局時,一般用SimpleAdapter,或者繼承BaseAdapter自己重寫。    如果是繼承ArrayAdapter,SimpleAdapter的時候,由於父類本身維護了一個List,所以當有數據更新的時候,盡量用adapter的add,這樣可以保證getCount()返回的值是正確。   這裡面涉及到的一個比較重要的重寫函數就是getView       在getView中有三種方式實現view的返回。       第一種方式:   最簡單也是最容易理解的是每一個view都通過inflate生成一個新的view進行返回   public View getView(int position, View convertView, ViewGroup parent) {           LayoutInflater inflater = LayoutInflater.from(context);            View item = inflater.inflate(R.layout.list_item_icon_text, null);        ((TextView) item.findViewById(R.id.text)).setText(DATA[position]);      ((ImageView) item.findViewById(R.id.icon)).setImageBitmap(         return item; } 這種方式,在數據量小的時候,劣勢不明顯,但是當一個listview裡面有大量條目時,這種方式就顯得非常浪費。因為每一次item的出現,消失或者更新時,都需要重新inflate。給內存造成了很大的消耗。   那麼還有什麼方式可以節省開銷呢?       第二種方式:   我們看看getView函數裡面conertview的是干啥的。查看官方文檔後發現:   convertView - The old view to reuse, if possible. Note: You should check that this view is non-null and of an appropriate type before using. If it is not possible to convert this view to display the correct data, this method can create a new view. Heterogeneous lists can specify their number of view types, so that this View is always of the right type (see Adapter.getViewTypeCount() and Adapter.getItemViewType(int)).     注:   getViewTypeCount()是用來當listview中有不同的種類的item,比如分割線之類的時候,用getItemViewType返回某個item的類型,然後坐不同的     原來converView是用來重用view的。經過查找別的資料。找到了一張比較經典的圖如下:           這張圖清楚的描述了listview是如何重用view的。listview通過getview分別請求所有可見項目。此時converview是空的。   當item1滑動出屏幕後,item8從下面滑動出來,此時又要調用getview,但是此時的converview已經不再為空了,而是上次一劃出屏幕的item1,此時我們只需要重新修改下item1的數據,而不必重新創建一個新的view。   這樣就節省了內存。       那麼由此我們得到了第二種方式     public View getView(int position, View convertView, ViewGroup parent) {  if (convertView == null) {    convertView = mInflater.inflate(R.layout.item, parent, false);  }    ((TextView) convertView.findViewById(R.id.text)).setText(DATA[position]);    ((ImageView) convertView.findViewById(R.id.icon)).setImageBitmap(    (position & 1) == 1 ? mIcon1 : mIcon2);    return convertView;  }       這種方式裡面,我們通過converview找到對應需要修改的text和ico,然後修改數據,進行返回。       有人會說,上面不已經解決了重用的問題了麼,還有第三種方式?       那麼我們下面看看google推薦的第三種方式是怎麼實現的。       static class ViewHolder { TextView text; ImageView icon; }     這裡定義了一個內部靜態類,     public View getView(int position, View convertView, ViewGroup parent) {  ViewHolder holder;    if (convertView == null) {  convertView = mInflater.inflate(R.layout.list_item_icon_text,  parent, false);  holder = new ViewHolder();  holder.text = (TextView) convertView.findViewById(R.id.text);  holder.icon = (ImageView) convertView.findViewById(R.id.icon);  convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } holder.text.setText(DATA[position]); holder.icon.setImageBitmap((position & 1) == 1 ? mIcon1 : mIcon2); return convertView; }           然後用convertView.setTag(holder)的方式將之前通過findViewById找到的textview與ImageView放入converivew對象中。   這樣當再次重用converview的時候,就不必再次利用findViewById來查找了,省掉了開銷。
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved