我有一個類似的問題,花了我2天來調試和解決它。 我有一個ListAdapter爲每個列表項在LinearLayout中創建幾個TextView。 每個TextView都有它自己的OnClickListener,因爲我需要處理每個項目的點擊。
當我更改實現,以便重用Views時,OnClickListener停止正常工作。在4.4.2上,大多數點擊都有效,但有時在我滾動列表之前沒有任何反應。在2.3上,第一次點擊將無法工作,然後在突發中處理所有點擊。
在我的特殊情況下,我創建了Java代碼中的所有視圖,而不是通過膨脹資源。 關鍵的一點是,即使視圖被重用(這似乎更安全,然後假定重用視圖具有正確的佈局參數),我仍然設置了LinearLayout的LayoutParams。 當我沒有設置LayoutParams時,重用一切工作正常! 這裏是關鍵代碼:
public View getView(int position, View convertView, ViewGroup parent) {
LinearLayout tapeLine = null;
if (convertView != null && convertView instanceof LinearLayout && ((LinearLayout)convertView).getChildCount() == 4) tapeLine = (LinearLayout) convertView; // Reuse view
else tapeLine = new LinearLayout(activity);
if (convertView == null) { // Don't set LayoutParams when reusing view
ViewGroup.LayoutParams tapeLineLayoutParams = new AbsListView.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
tapeLine.setLayoutParams(tapeLineLayoutParams);
}
ScrollingTape scrollingTape = calculatorHolder.getCalculator().getScrollingTape();
int tapeWidthPx = parent.getWidth();
TapeLineTextSizeInfo tapeLineTextSizeInfo = calculatorHolder.getTapeLineTextSizeHelper().createTapeLineTextSizeInfo(tapeWidthPx);
ScrollingTapeLine line = scrollingTape.getLine(position);
tapeLine.setOrientation(LinearLayout.HORIZONTAL);
int tapeBackgroundColor = getBackgroundColor(line);
tapeLine.setBackgroundColor(tapeBackgroundColor);
addColumnViews(tapeLine, line, tapeLineTextSizeInfo);
tapeLine.setTag(R.id.scrollingtapeadapter_viewtag_position, position);
tapeLine.setOnLongClickListener(longClickListener);
tapeLine.setOnClickListener(remainClickListener);
return tapeLine;
}
什麼是列表視圖的這種奇怪的行爲的背景是什麼? 我在Android源代碼中進行了一些調試和研究。 當android更新視圖時,onMeasure和onLayout有兩個重要步驟。 ListAdapter的getView方法不僅被調用來繪製視圖,而且在onMeasure期間也被調用。在後面這種情況下,視圖被創建,但它尚未在事件鏈中註冊以處理點擊事件。
當爲onMeasure創建的視圖稍後被重新用於畫面時,它必須從Android系統註冊以處理點擊事件。 對於這種特殊情況,Android開發者已經做了一些事情,這可能被認爲是骯髒的黑客攻擊。 LayoutParams中的特殊標誌用於決定視圖必須在事件更改中註冊。
現在我的問題:通過重置LayoutParams還視圖重用時,此標誌始終重置。因此,Android系統不會註冊視圖,事件不會通過。
總結:當在ListView的getView中重新使用視圖時,不要覆蓋LayoutParams,因爲它們保留了android系統的內部信息。
我使用Loaders特別是AsyncLoader來完成我所有的後臺進程。但我會重新評估代碼,謝謝你的提示! – Bostone 2012-01-11 16:19:26
畢竟不是理由。查看我的回答 – Bostone 2012-02-07 01:26:43