2010-06-26 79 views
7

我有一個動態的ListView它使用ArrayAdapter。當從微調器中選擇一個名稱時,該名稱連同顯示他們是男性還是女性的圖標將被添加到ListViewListView with ArrayAdapter和ViewHolder將圖標添加到錯誤的項目

大部分情況都是好的(名字被正確添加到列表中,並附帶一個圖標)。但顯示性別的圖標被添加到ListView中的錯誤項目中。該名稱被添加到列表的底部,但該圖標被放置在列表頂部的名稱處。我不知道這是我使用ViewHolder的方式,但Android website中沒有文檔。

// Listview inflater 
inflater = (LayoutInflater) (this).getSystemService(LAYOUT_INFLATER_SERVICE); 

// List Array. 
mAdapter = new ArrayAdapter<String>(this, R.layout.player_simple_list, 
               R.id.label, mStrings) { 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 

     Log.i("ANDY","View getView Called"); 
     // A ViewHolder keeps references to children views to 
     // avoid unneccessary calls to findViewById() on each row. 
     ViewHolder holder; 

     if (null == convertView) { 
      Log.i("ANDY","Position not previously used, so inflating"); 
      convertView = inflater.inflate(R.layout.player_simple_list, null); 
      // Creates a ViewHolder and store references to the 
      // two children views we want to bind data to. 
      holder = new ViewHolder(); 
      holder.text = (TextView) convertView.findViewById(R.id.label); 
      holder.icon = (ImageView) convertView.findViewById(R.id.icon); 
      if (sexmale == true) { 
       holder.icon.setImageBitmap(maleicon); 
      } 
      else { 
       holder.icon.setImageBitmap(femaleicon); 
      } 
      convertView.setTag(holder); 
     } else { 
      // Get the ViewHolder back to get fast access to the TextView 
      // and the ImageView. 
      holder = (ViewHolder) convertView.getTag(); 

     } 
     // Bind the data efficiently with the holder. 
     holder.text.setText(getItem(position)); 
     // Change icon depending is the sexmale variable is true or false. 
     Log.i("ANDY","getCount = "+mAdapter.getCount()); 
     return convertView; 
    } 
}; 
setListAdapter(mAdapter); 
+0

有一些公平的文件有:https://developer.android.com/training/improving-layouts/smooth-scrolling.html – Vince 2014-10-23 20:22:32

回答

1

更新:ViewHolder只是爲了保存對項目佈局內組件的觀點引用。這有助於避免調用findViewById來渲染具有多個組件的複雜項目佈局中的每個組件的開銷(如在此例中爲TextViewImageView)。

我通過使用例程(稱爲getSex)檢索性別數據並設置所有視圖數據(包括if-else塊外部的圖標)來修復它。

工作的代碼現在看起來是這樣的:

if (null == convertView) { 
    Log.i("ANDY","Position not previously used, so inflating"); 
    convertView = inflater.inflate(R.layout.player_simple_list, null); 

    // Creates a ViewHolder and store references to the two children views 
    // we want to bind data to. 
    holder = new ViewHolder(); 
    holder.text = (TextView) convertView.findViewById(R.id.label); 
    holder.icon = (ImageView) convertView.findViewById(R.id.icon); 
    convertView.setTag(holder); 
} else { 
    // Get the ViewHolder back to get fast access to the TextView 
    // and the ImageView. 
    holder = (ViewHolder) convertView.getTag(); 
} 

// Bind the data efficiently with the holder. 
holder.text.setText(getItem(position)); 
// Change icon depending is the sexmale variable is true or false. 
if (getSex (getItem(position)) == true) { 
    holder.icon.setImageBitmap(maleicon); 
} 
else { 
    holder.icon.setImageBitmap(femaleicon); 
} 
return convertView; 
1

你必須從如果幾行數據的註釋後移動,如本question is explained

// Bind the data efficiently with the holder. 

所以它看起來像這樣

if (null == convertView) { 
    Log.i("ANDY","Position not previously used, so inflating"); 
    convertView = inflater.inflate(R.layout.player_simple_list, null); 
    // Creates a ViewHolder and store references to the two children views 
    // we want to bind data to. 
    holder = new ViewHolder(); 
    convertView.setTag(holder); 
} else { 
    // Get the ViewHolder back to get fast access to the TextView 
    // and the ImageView. 
    holder = (ViewHolder) convertView.getTag(); 
} 

// Bind the data efficiently with the holder. 
holder.text = (TextView) convertView.findViewById(R.id.label); 
holder.icon = (ImageView) convertView.findViewById(R.id.icon); 
if (sexmale == true) { 
    holder.icon.setImageBitmap(maleicon); 
} 
else { 
    holder.icon.setImageBitmap(femaleicon); 
} 
holder.text.setText(getItem(position)); 
+3

我不同意,這會使'ViewHolder'無用,因爲每次都覆蓋它。正確的解決方案應該在'if'分支中設置'holder.text'和'holder.icon',並在'if'塊之外設置內容('setText','setImageBitmap')。 – cristis 2010-06-26 09:21:57

+0

我認爲覆蓋需要在那裏,因爲如果沒有,它會保存與其他記錄位置有關的數據。例如,如果顯示記錄10,並且如果將重新使用來自記錄3的緩存視圖,則如果不覆蓋記錄3的數據集,則記錄10將可見。 – Pentium10 2010-06-26 09:40:15

+1

@ Pentium10:否,cristis是正確的。 「ViewHolder」綁定到行,所以它保存的小部件不會改變。需要改變的只是這些小部件的內容。 – CommonsWare 2010-06-26 09:52:52

2

你必須設置if-else-if後面的圖標來創建或綁定holder。否則,僅在列表中的前幾個項目才正確顯示圖標,即直到ListView未被填充。

public View getView(int position, View convertView, ViewGroup parent) { 

    Log.i("ANDY","View getView Called"); 
    // A ViewHolder keeps references to children views 
    // to avoid unneccessary calls to findViewById() on each row. 
    ViewHolder holder; 

     if (null == convertView) { 
      Log.i("ANDY","Position not previously used, so inflating"); 
      convertView = inflater.inflate(R.layout.player_simple_list, null); 

      // Creates a ViewHolder and store references to 
      // the two children views we want to bind data to. 
      holder = new ViewHolder(); 
      holder.text = (TextView) convertView.findViewById(R.id.label); 
      holder.icon = (ImageView) convertView.findViewById(R.id.icon); 
      convertView.setTag(holder); 
     } else { 
      // Get the ViewHolder back to get fast access to the TextView 
      // and the ImageView. 
      holder = (ViewHolder) convertView.getTag(); 

     } 
     // Bind the data efficiently with the holder. 
     holder.text.setText(getItem(position)); 

     // Change icon depending is the sexmale variable is true or false. 
     if (sexmale == true) { 
      holder.icon.setImageBitmap(maleicon); 
     } 
     else { 
      holder.icon.setImageBitmap(femaleicon); 
     } 
     Log.i("ANDY","getCount = "+mAdapter.getCount()); 
     return convertView; 
} 
+0

嗨。我試過了,但所有的圖標都變成了相同的類型,都在列表中。即如果選擇了男性名字,則所有圖標都變成男性。 – 2010-06-27 08:30:44

相關問題