2013-03-14 13 views
1

我碰到這個問題好幾次,很容易找到一個快速搜索很多類似的問題。有時ListView行佈局上的動態更改也會影響其他行,有時它不會。爲什麼自定義適配器的列表視圖有時會表現奇怪?

作爲這個問題的解決方案,我通常跟蹤列表中的整個項目集,每當我有變化時,我都重置列表中的所有項目。例如:如果我有一個帶TextViews和複選框的列表,我必須保留一個布爾值數組,指示每個複選框的狀態,並且在我的getView()覆蓋函數中重置所有基於該數組的複選框。

這是預期嗎?我可以找到關於這個問題的幾個問題,所有的解決方案似乎都與我的相似。

現在我面臨一個問題,我需要一次跟蹤多個項目(背景,複選框和文本)在一個非常長的列表中。我想知道是否有任何其他方法來解決這個問題。

回答

1

你這樣做是正確的。在Android中,您應該跟蹤每個單獨列表項的狀態。當調用getView時,您可以選擇重新使用或爲該行創建新視圖。通過跟蹤項目的狀態(文本,選中,背景等),您可以輕鬆地重置已存在的視圖。詳細的狀態飼養軌道將幫助您確保沒有其他行是由一個行的變化

影響你打電話時adapter.notifyDataSetChanged()被重繪是那些在屏幕上(或非常接近,是在屏幕上)唯一的項目。

+0

你有什麼參考嗎?我怎樣才能找出哪些項目重新繪製? AFAIK這是完全隨機的,當我做出改變時,哪些項目會「破碎」。 – caiocpricci2 2013-03-14 13:49:56

+0

這是Google的API規範ListView的。我敢打賭,正在發生的事情是,您正在重新使用一個視圖,而您並未重置所有狀態。因此,一些複選框不應該被檢查,反之亦然。當你滾動列表(上下)時,你會看到越來越多的奇怪行爲。 – Sababado 2013-03-14 15:54:15

2

這是Android中ListViews的預期行爲。您使用基礎數據來填充列表中的視圖的方法正確。

Android在創建ListView時使用了一種名爲View Recycling的技術,因爲與使用數據填充視圖相比,膨脹視圖是一項強化操作。 Android只通過創建用戶在屏幕上看到的視圖來將通貨膨脹降到最低(在程序員的幫助下)。當用戶向上滾動列表時,移出屏幕的視圖將被放置在一個池中,以供將要顯示的新項目重新使用。作爲第二個參數,此池中的視圖傳遞給getView。這個視圖將保持其從列表中彈出的確切狀態,所以取決於getView方法是否清除舊數據的任何狀態,並根據基礎數據中的新狀態重新填充它。下面是getView()的實施應該有結構的一個例子:

@Override 
public View getView (int position, View convertView, ViewGroup parent) 
{ 
    //The programmer has two responsibilities in this method. 

    //The first is to inflate the view, if it hasn't been 
    //convertView will contain a view from the aforementioned pool, 
    // but when first creating the list, the pool is empty and convertView will be null 
    if(convertView == null) 
    { 
     //If convertView is null, inflate it, something like this.... 
     convertView = layoutInflator.inflate(R.layout.mylistview, null); 
    } 

    //If convertView was not null, it has previously been inflated by this method 

    //Now, you can use the position argument to find this view's data and populate it 
    //It is important in this step to reset the entire state of the view. 
    //If the view that was popped off the list had a checked CheckBox, 
    // it will still be selected, EditTexts will not be cleared, etc. 

    //Finally, once that configuration is done, return convertView 
    return convertView; 
} 

有來自適配器類也有許多其他方法,可幫助管理您的列表,並允許你做聰明的事情,槓桿融資的回收,如getItem()用於管理您的基礎數據,而getViewType()getViewTypeCount()針對具有多種視圖類型的列表,但以上是基本技巧,並且是視圖順利運行所需的最少量。

這聽起來像你在正確的軌道上,我希望這有助於回答你的一些問題。如果有什麼不清楚的地方,請告訴我更多信息。

相關問題