2012-09-29 48 views
2

時,點擊被錯誤的對象處理我有一個經常更新的Android ListView。當我點擊列表中的一個項目時,錯誤對象獲取點擊事件的時間的一部分。即使更新沒有更改列表,也會發生這種情況。listview adapter當notifyDataSetChanged頻繁地被調用並且視圖膨脹從佈局

我只是編碼這個錯誤,或者是否有通過視圖層次結構處理事件的競爭條件?

ListView使用擴展BaseAdapter的適配器,其getView()方法如下所示。但只有當USE_LAYOUT = true時纔會出現此問題。

@Override 
public View getView(final int position, View convertView, ViewGroup parent) { 
    View view; 
    TextView textView; 
    ViewHolder viewHolder; 

    if (convertView == null) { 
     if (USE_LAYOUT) { 
      view = context.getLayoutInflater().inflate(R.layout.row, parent, false); 
      textView = (TextView) view.findViewById(R.id.rowTextView); 
     } else { 
      view = new TextView(context); 
      textView = (TextView) view; 
     } 
     viewHolder = new ViewHolder(); 
     viewHolder.textView = textView; 
     view.setTag(viewHolder); 
    } else { 
     view = convertView; 
     viewHolder = (ViewHolder) view.getTag(); 
     textView = viewHolder.textView; 
    } 

    final String item = getItem(position); 
    textView.setText(position + " " + item); 
    textView.setOnClickListener(new OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      Log.d("Adapter", position + " " + item); 
     } 
    }); 

    return view; 
} 

因此在上面的代碼而言,活性呈現出「1條1/1」的列表視圖,「2 ITEM2」,「3項目3」等,如果我按一下,說項目3,的某個百分比時間,日誌會顯示「21 item21」。

一對夫婦對代碼的其他要點:

  • 該項目只是一個字符串,適配器保持List<String>getItem()只是調用items.get(index)setItems()設置列表,並調用notifyDataSetChanged()
  • 如果列表未更改,則會出現問題。也就是說,定時器調用setItems(new ArrayList<String>(getItems())
  • setItems()通過runOnUiThread()從UI線程調用。
  • 計時器每隔500ms左右關閉一次,但其他頻率出現問題。
  • 行佈局只是一個LinearLayout中的TextView。

我觀察到,當通過getView回收視圖時,它們按相反順序回收。換句話說,當調用notifyDataSetChanged()並且列表沒有滾動時,第一個項目與最後一個項目一起被回收,第二個項目與第二個到最後一個項目一起被回收,等等。因此,我懷疑競爭狀態。此外,我觀察它在2.1和2.3,但不是4.0(雖然我不確定它從來沒有發生那裏)。

+0

我有與listview.notifyDataSetChanged()方法相同的問題,如果任何圖像更新後設置adpter和我fireifyDataSetChanged(),然後一段時間,圖像布萊恩到其他位置,並回來,所以圖標閃爍。 –

+1

那麼你有什麼解決方案嗎?如果是的話,你能否給我解決方案。 –

回答

0

的問題是,在onClick()方法的代碼是在不同的時間比運行時getView()執行,所以position可能不是你所期望它是...試試這個:

final String item = getItem(position); 
textView.setTag(position); 
textView.setText(position + " " + item); 
textView.setOnClickListener(new OnClickListener() { 
    @Override 
    public void onClick(View v) { 
     int position = (Integer) v.getTag(); 
     Log.d("Adapter", position + " " + getItem(position)); 
    } 
}); 

在換句話說裏面的一切new OnClickListener() { ... }無法看到當地變量裏面getView()(如positionitem),但可以看到變量和方法(如getItem())。

+0

由於'position'是最終的,我相信''onClick()'運行時它的值與'getView()'運行時的值相同。通過最終值或通過標籤傳遞是等效的。無論如何,我嘗試了標記方法並獲得相同的行爲。 – nw010101

相關問題