2014-03-05 75 views
2

要更新列表視圖,我們可以做以下兩件事:什麼更昂貴?每次數據更改或更新現有的ArrayAdapter時,都會創建一個新的ArrayAdapter?

1)創建一個新的ArrayAdapter並在每次數據更新時將其綁定到ListView。

this.listView.setAdapter(new ArrayAdapter(getActivity(), data)); 

2)更新其已綁定到列表視圖一個ArrayAdapter的內容:

this.arrayadapter.clear(); 
for (Data item : data) 
    this.arrayadapter.add(item); 
this.arrayadapter.notifyDataSetChanged(); 

所以該方法是更昂貴的?

回答

2

你這樣做的方式,第二個肯定是更昂貴的。 ArrayAdapterclear()以及add()內部調用notifyDataSetChanged()。你可以將其更改爲

this.arrayadapter.setNotifyOnChange(false); 
this.arrayadapter.clear(); 
for (Data item : data) 
    this.arrayadapter.add(item); 
this.arrayadapter.setNotifyOnChange(true); 
this.arrayadapter.notifyDataSetChanged(); 

但即使是這樣,兩個通話包含一個synchronized塊,這使得他們慢。所以即使你在第一種方法中創建了一個新的ArrayAdapter,我會說它更快。

您可以通過使用自定義適配器和setItems(data)方法進一步優化它,該方法僅替換內部數據列表。

+0

根據文檔,調用'notifyDataSetChanged()'將NotifyOnChange'標誌重置爲true,因此不需要行。 – user1032613

2

我願意接受答案的最終結論。儘管SimonSays在迭代方面提出了有效的觀點,並添加了......但是設置他無法識別的新適配器會發生很多事情。這使得很難說它是否有更好的建議......每種方法。

設置一個新的適配器將導致ListView清除它的所有回收視圖。它還必須重新測量所有進入的新視圖......這導致getView()被稱爲每個項目3-4個位置的幾個位置......如果不是全部位置。 (隨平臺而異)。因此,即使添加了同步塊,您可能會看到getView方法調用的時間少得多,並可能使用循環視圖。

基本上,知道哪個更好比較困難,並且很大程度上取決於用例。爲了更好的可讀性,我會投票堅持......每種方法。

+1

我同意你的意見。當你有一個自定義適配器和一個「重」項目(在你的自定義項目中有多個視圖)時,重新繪製它們(重置getView回收器)並創建一個新的Adapter-實例,性能比for循環更糟糕(不太明顯儘管默認的ArrayAdapter)。我會說使用'this.arrayadapter.addAll(dataList);'而不是for循環。陣列適配器很可能會在幕後使用for-loop(我認爲),但也許它會更好地優化,它也只會調用'notifyDataSetChanged()'兩次('clear'和'addAll'),而不是每個' add'。 –

相關問題