
網上找了一張圖, listview 異步加載圖檔之是以錯位的根本原因是重用了 convertview 且有異步操作.
如果不重用 convertview 不會出現錯位現象, 重用 convertview 但沒有異步操作也不會有問題。
我簡單分析一下:
當重用 convertview 時,最初一屏顯示 7 條記錄, getview 被調用 7 次,建立了 7 個 convertview.
當 item1 劃出螢幕, item8 進入螢幕時,這時沒有為 item8 建立新的 view 執行個體, item8 複用的是
item1 的 view 如果沒有異步不會有任何問題,雖然 item8 和 item1 指向的是同一個 view,但滑到
item8 時刷上了 item8 的資料,這時 item1 的資料和 item8 是一樣的,因為它們指向的是同一塊記憶體,
但 item1 已滾出了螢幕你看不見。當 item1 再次可見時這塊 view 又涮上了 item1 的資料。
但當有異步下載下傳時就有問題了,假設 item1 的圖檔下載下傳的比較慢,item8 的圖檔下載下傳的比較快,你滾上去
使 item8 可見,這時 item8 先顯示它自己下載下傳的圖檔沒錯,但等到 item1 的圖檔也下載下傳完時你發現
item8 的圖檔也變成了 item1 的圖檔,因為它們複用的是同一個 view。 如果 item1 的圖檔下載下傳的比
item8 的圖檔快, item1 先刷上自己下載下傳的圖檔,這時你滑下去,item8 的圖檔還沒下載下傳完, item8
會先顯示 item1 的圖檔,因為它們是同一快記憶體,當 item8 自己的圖檔下載下傳完後 item8 的圖檔又刷成
了自己的,你再滑上去使 item1 可見, item1 的圖檔也會和 item8 的圖檔是一樣的,
因為它們指向的是同一塊記憶體。
最簡單的解決方法就是網上說的,給 imageview 設定一個 tag, 并預設一個圖檔。
當 item1 比 item8 圖檔下載下傳的快時, 你滾下去使 item8 可見,這時 imageview 的 tag 被設成了
item8 的 url, 當 item1 下載下傳完時,由于 item1 不可見現在的 tag 是 item8 的 url,是以不滿足條件,
雖然下載下傳下來了但不會設定到 imageview 上, tag 辨別的永遠是可見 view 中圖檔的 url。
關鍵代碼如下:
我參考網上資料寫了一個 listview 異步加載圖檔的 demo:
(1) asynctask 下載下傳圖檔
(2) 實作記憶體、檔案二級緩存
記憶體緩存使用 lrucache,檔案緩存使用 disklrucache