在Android上的ListView中加载延迟图像

时间:2010-09-22 06:36:24

标签: android android-listview lazy-loading

我在ListView中实现了延迟加载图片。 我使用AsyncTask从互联网上下载图像并将其绑定到UIThread中的ImageView。

除了当我快速滚动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);
    }
}

2 个答案:

答案 0 :(得分:7)

在ListView中延迟加载图像时会出现两个问题。

  1. 旧图像仍会显示,直到加载新图像。在开始图像下载之前,只需将ImageView设置为图像即可加载视图或将其设置为不可见。
  2. 第二个问题难以解决。想象一下,你在列表中滚动非常快。现在,在旧的AsyncTask加载图像之前,您的视图可以被回收。您现在有两个正在运行的任务,在onPostExecute方法中将图像设置为imageview。现在短时间内将显示错误的图像,直到第二个任务完成,或者更糟糕的是由于某些网络相关的原因,它们没有按照它们开始的顺序完成,并且您有错误的图像覆盖正确的图像。要解决此问题,您必须检查任务完成后应显示的图像。在View类中有两种方法可以完全像这样:

    setTaggetTag您可以将任何对象绑定到您脑海中的imageview。在大多数情况下,在开始任务之前,我使用setTag将图像的URL作为String绑定到imageview。现在,我可以在任务完成后将getTag强制转换为String,并将应显示的URL与我下载的URL进行比较,并在必要时仅设置图像。

答案 1 :(得分:2)

在适配器中创建一个名为void setBitmap(Bitmap bitmap, int position)或类似的函数。当新位图可用时,让AsyncTask调用此方法。然后,此方法可以在UI-Thread本身上调用notifyDataSetChanged()以确保视图得到刷新。在适配器中保持对视图的引用(即使将它们保存在AsyncTask中)也很危险!