ListView显示错误和重复的图像

时间:2014-05-02 16:03:38

标签: android listview android-listview android-imageview android-image

我有一个ListView和12个ImageViews。

每个ImageView都有不同的图片,从网址加载。无论是否滚动,图像都会被洗牌,有时也会重复。

我尝试了其他10种方法来解决这个问题,但没有成功。

这是我下载并显示图片的代码:

private static class ViewHolder {
    ImageView imageViewPhoto;

    Bitmap photo;
    boolean isDownloading;
}

@Override
public View getView(final int position, View convertView, ViewGroup parent) {
    final ViewHolder viewHolder;

    if (convertView == null) {

        // ...classical view holder and other operations...

        if (!viewHolder.isDownloading) {

            viewHolder.isDownloading = true;

            IImageDownload downloadInterface = new IImageDownload() {

                @Override
                public void onError(VolleyError error, String url) {
                }

                @Override
                public void onDownloaded(Bitmap response, String url) {

                        viewHolder.photo = response;
                    notifyDataSetChanged();
                }
            };

            imageDownloader.downloadImage(dataList.get(position).getPhotoPath(), true, downloadInterface);

        convertView.setTag(viewHolder);
    } else {
        viewHolder = (ViewHolder) convertView.getTag();
    }



    if (viewHolder.photo != null) {
        viewHolder.imageViewPhoto.setImageBitmap(viewHolder.photo);
    } else {
        viewHolder.imageViewPhoto.setImageResource(R.drawable.gray_background);
    }

}

提前感谢任何想法!

3 个答案:

答案 0 :(得分:4)

在:

imageDownloader.downloadImage(dataList.get(position).getPhotoPath(), true, downloadInterface);

把:

viewHolder.photo.setImageBitmap(null);

这将重置ImageView的位图,因为它正在被回收并因此保持其图像。

答案 1 :(得分:2)

你应该有这样的东西:

if (!viewHolder.isDownloading) {
    // download the image in a worker thread
} else {
    // cancel the current downloading and start a new one with the new url
}

由于ListView项目为reusable。您的项目正在开始图像下载,但是当您开始滚动时,这些相同的项目仍然可以在它们已被重用时下载图像。因此,当工作线程完成后,位图设置在错误的位置,更糟糕的是,您从未开始下载这些重用项目,因为viewholder.isDownloading表示它已经下载了图像。

答案 2 :(得分:1)

A)您只在实例化convertView时启动下载。您正在回收行,因此您的数据集可能大于实际使用的行View的数量。这不是开始下载图像的正确位置。您希望每个查看的位置执行此操作,而不是按View实例化。

B)当您启动后台任务以下载图像时,它可能会在稍后(在获取之后)返回并用错误的图像替换行,因为该行现在可能表示错误的位置(给定行回收)。

回收ListView中的异步图像加载比最初看起来稍微复杂一些。当用户滚动列表时,您需要在查看位置时触发下载,并取消现在多余的呼叫(因为它们是先前可见的位置)。

您可能希望在ListView中详细了解视图回收,以便更好地了解正在发生的事情。

还可以考虑使用处理Picasso等复杂性的图像下载/缓存库。