2013-10-30 32 views
0

我對this question的答案使用了類似的方法。唯一真正的區別是,我不是基於SoftReference<Bitmap的高速緩存,而是將圖像保存到/data/data/my.app/files,因爲它們預計不會變得太頻繁。我的適配器的getView()功能:如果我沒有預設ImageView圖像,延遲加載圖片纔有效?

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 
    //data from your adapter 
    MyItem entry = getItem(position); 
    //we want to reuse already constructed row views... 
    if (convertView == null) { 
     convertView = LayoutInflater.from(context).inflate(R.layout.appitem, null); 
    } 

    convertView.setTag(entry); 

    TextView Name = (TextView)convertView.findViewById(R.id.Name); 
    TextView Version = (TextView)convertView.findViewById(R.id.Version); 
    final ImageView Icon = (ImageView)convertView.findViewById(R.id.Icon); 

    Name.setText(entry.getName()); 
    Version.setText(entry.getVersion()); 
    Icon.setImageResource(R.drawable.default_icon); // the problem line 

    try { 
     final String _id = entry.getID(); 

     imageLoader.loadImage(_id, "<my url>", new ImageThreadLoader.ImageLoadedListener() { 
      public void imageLoaded(Bitmap imageBitmap) { 
       Icon.setImageBitmap(imageBitmap); 
       notifyDataSetChanged(); 
      } 
     }); 
    } catch (Throwable t) { 
     Log.e("","", t); // nothing is hitting this log 
    } 

    return convertView; 
} 

標有「問題線」之上,我的圖標設置爲默認的圖標,如果我刪除了這一行接下來的事情大多是好的工作(當次重複使用,它會顯示舊圖片不久之後才顯示新的)。如果該行存在,則圖像不會變爲其他任何內容。匿名ImageLoadedListener仍然在UI線程上運行,並在那裏設置斷點顯示一切似乎正常發生。我也知道ImageThreadLoader工作正常。這些文件出現在他們應該看的地方,並且看起來很好(當上面的問題行被刪除時,它們可以正常加載)。

爲什麼提前設置圖像會導致以後無法更新?

+0

#1在imageLoaded(位圖)中添加一個try-catch *並記錄imageBitmap值(== null?) – Loda

+0

添加try/catch。沒有什麼被拋出。在我的調試中,它也永遠不會返回null。 –

+0

你不能「調試」(即:與調試器)與線程和更改UI元素相關的問題。最可愛的輸出是它可以與調試器一起工作,但並非沒有。使用Log.e()。 – Loda

回答

2

a hunch:

刪除notifyDataSetChanged()。

爲什麼?調用adapter.notifyDataSetChanged()將提供列表的全部刷新(即:每個視圖的)。所以,每個項目的新調用getView(位置)。在這次調用中,您將圖像再次更改爲default_icon。這只是在設置好之後追加!

所以序列是:對於一個圖像,負載從磁盤的一個圖像設定default_icon,無效 - >組默認爲ALL,負載從磁盤的一個圖像,....

編輯:澄清的說明中,除去假設關於線程限制。

+0

頭部/線程限制?我不確定我是否遵守。該實現不會爲每個列表項啓動1個線程,它只會添加到1個線程處理的隊列中。無論如何,刪除notifyDataSetChanged似乎神祕似乎工作。 –

+0

我不知道imageLoader的實現,我剛看到「new xxxThreadxx()」 – Loda

+0

它本質上是一個隊列和一個同步塊在單線程上運行。我很驚訝,刪除通知使它工作。好吧。 –