2010-09-22 66 views
6

我在我的ListView中實現了延遲加載圖像。 我使用AsyncTask從互聯網下載圖像,並將其綁定到UIThread中的ImageView。在Android上的ListView中延遲加載圖像

它的工作除了當我滾動ListView變化很快,下載的圖像有時被綁定到列表中的錯誤項目。

我想問題來自convertViewBaseAdapter的重用。 任何想法來解決它?

非常感謝。

編輯: 我張貼的答案如下:

public void setBitmap(int position, Bitmap image) { 
    View itemView = mListView.getChildAt(position - mListView.getFirstVisiblePosition()); 
    if (itemView != null) { 
     ImageView itemImageView = (ImageView) itemView.findViewById(R.id.item_imageview); 
     itemImageView.setImageBitmap(image); 
    } 
} 
+0

我在這裏嘗試的例子http://android-developers.blogspot.com/2010/07/multithreading-for-performance.html它的工作原理,但仍然得到了錯誤的圖像結合的機會。技巧比較任務的實例看起來與Janusz的答案相同。但它使用弱引用來保存ImageView的實例。需要深入挖掘。有任何想法嗎? – shiami 2010-09-24 02:10:15

回答

2

創建一個名爲void setBitmap(Bitmap bitmap, int position)或適配器類似的功能。當新的位圖可用時,讓您的AsyncTask調用此方法。此方法可能會在UI線程本身上調用notifyDataSetChanged()以確保刷新視圖。在適配器中保存對視圖的引用(即使將它們保存在AsyncTask中)也很危險!

+0

這不是shiami所具有的問題。他正在重複使用具有圖像集的視圖,並且因爲在異步任務中設置了正確的圖像,所以顯示舊圖像直到新圖像加載等。 – Janusz 2010-09-22 07:25:45

+1

是的。我曾經在一個項目中發生過這種行爲,並且使用setTag()或getTag()只是一個醜陋的解決方法。解決方案是直接在getView()方法中設置位圖,該方法本身由notifyDataSetChanged()觸發。當然這會導致刷新所有可見的視圖,這可能會導致一個明顯的口吃。要刷新一個視圖,該解決方案可能會更好:http:// stackoverflow。com/questions/3724874/android-update-single-item-in-list – mreichelt 2010-09-22 08:24:28

+0

感謝您的提示。但是,我可以在哪裏獲得正確的視圖實例,以根據給定的位置綁定我下載的圖像? – shiami 2010-09-23 09:44:04

7

在ListView中延遲加載圖像時會出現兩個問題。

  1. 舊圖像仍顯示,直到新的圖像加載。這很簡單,只需將ImageView設置爲正在加載視圖的圖像,或者在開始下載圖像之前將其設置爲不可見。
  2. 第二個問題很難解決。想象一下,你在列表中快速滾動。現在您的視圖可能會在舊的AsyncTask完成加載圖像之前被回收。您現在有兩個任務正在運行,onPostExecute方法會將圖像設置爲imageview。現在很短的時間內,將顯示錯誤的圖像,直到第二個任務完成,或者更糟的是,由於某些網絡相關的原因,他們沒有按照他們開始的順序完成,並且您有錯誤的圖像覆蓋正確的圖像。爲了解決這個問題,你必須檢查任務完成後應該顯示的圖像。在View類中有兩種方法與此類似:

    setTaggetTag您可以將任何對象綁定到進入您的頭腦的圖像視圖。在大多數情況下,我使用setTag將圖像的URL作爲字符串綁定到imageview,然後開始執行任務。現在,我可以在任務完成後將getTag轉換爲字符串,並將應顯示的URL與我下載的URL進行比較,並在必要時僅設置圖像。

+0

謝謝!你描述的第一個問題似乎不是我的解決方案。因爲當滾動速度變化很快時,「ImageView」會被綁定數次。因此,將ImageView設置爲加載圖像或不可見不起作用。 – shiami 2010-09-23 10:03:57

+0

getTag方法似乎不會立即綁定「ImageView」,因爲標籤在滾動後更改。只有在慢慢滾動後才能更新。有沒有不正確的步驟? – shiami 2010-09-23 10:14:01

+0

我不明白你的意思與getTag不會立即綁定ImageView,所以我不能告訴你是否做錯了什麼。 – Janusz 2010-09-23 10:18:43