Listview 显示错误的图像 [英] Listview shows wrong images

查看:25
本文介绍了Listview 显示错误的图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有 ArrayAdapter 的 ListView,其中包含带有图像和字符串的行.这工作得很好,直到我决定图像的加载速度很慢,所以在显示列表之前我无法加载图像.所以我开始使用 AsyncTask 在单独的线程中加载图像.

I have a ListView with an ArrayAdapter holding rows with a Image and a String. This worked fine until I decided that the loading of the images was to slow so I could not load the images before showing the list. So I started to load the images in a separate thread using an AsyncTask.

在开始滚动列表之前,我对结果非常满意.加载了错误的图像,看起来这不是图像稍后获取的问题.如果我尝试对列表进行排序,问题就会变得非常糟糕,并且没有图像在正确的行上.

I was very happy with the result until I started to scroll the list. Wrong images was loaded and it doesn't look like it is a question of the image getting a while later. If I attempt to sort the list the problem goes really bad and none of the images is on the right row.

对我做错了什么有任何想法吗?

Any ideas of what I'm doing wrong?

public View getView(int position, View convertView, ViewGroup parent) {
        View v = convertView;
        ImageView imageView;
        TextView textView;
        if (v == null) {
            LayoutInflater vi = (LayoutInflater) getContext().getSystemService(
                    Context.LAYOUT_INFLATER_SERVICE);
            v = vi.inflate(R.layout.drink_list_row, null);
        }

        Drink drink = allItems.get(position);
        if (drink != null && v != null) {
            imageView = (ImageView) v.findViewById(R.id.picture);
            textView = (TextView) v.findViewById(R.id.drinkName);
            imageView.setVisibility(View.GONE);
            loadImageBitmap(drink, imageView);
            textView.setText(drink.getName());

            if (subItems != null && subItems.contains(drink)) {
                textView.setVisibility(View.VISIBLE);
                imageView.setVisibility(View.VISIBLE);
            } else {
                textView.setVisibility(View.GONE);
                imageView.setVisibility(View.GONE);
            }
        }
        return v;
    }

推荐答案

问题出在你的convertView:它是整个列表中使用的同一个实例,所以当你的异步加载完成时,图像会在listview 正在尝试使用相同的 convertView(或者在这种情况下,它的子 imageView)绘制不同的项目.

The problem comes from your convertView: it's the same single instance that is used throughout the list, so when your asynchronous loading is complete, the image is changed when the listview is trying to paint a different item using the same convertView (or in that case, its child imageView).

painting position 1, uses placeholder, starts loading image 1 asynchronously
painting position 2, uses placeholder, starts loading image 2 asynchronously
image 1 loading is complete, calling setImageBitmap on imageView
painting position 3, uses image 1, starts loading image 3 asynchronously
etc.

您可以做的是在列表适配器中保留位图缓存.像这样的:

What you can do though is keep a cache of Bitmaps in the listadapter. Something like this:

private Bitmap[] bitmapList;
private Bitmap bitmapPlaceholder;  

private void initBitmapListWithPlaceholders(){ 
// call this whenever the list size changes
// you can also use a list or a map or whatever so you 
// don't need to drop all the previously loaded bitmap whenever 
// the list contents are modified
    int count = getListCount();
    bitmapList = new Bitmap[count];
    for(int i=0;i<count;i++){
         bitmapList[i]=bitmapPlaceholder
    }
}

private void onBitmapLoaded(int position, Bitmap bmp){
// this is your callback when the load async is done
    bitmapList[position] = bmp;
}

public View getView(int position, View convertView, ViewGroup parent) {
    View v = convertView;
    ImageView imageView;
    TextView textView;
    if (v == null) {
        LayoutInflater vi = (LayoutInflater) getContext().getSystemService(
                Context.LAYOUT_INFLATER_SERVICE);
        v = vi.inflate(R.layout.drink_list_row, null);
    }

    Drink drink = allItems.get(position);
    if (drink != null && v != null) {
        imageView = (ImageView) v.findViewById(R.id.picture);
        textView = (TextView) v.findViewById(R.id.drinkName);
        imageView.setVisibility(View.GONE);
        imageView.setImageBitmap(bitmapList[position]);
        loadImageBitmap(drink, position); // this should call onBitmapLoaded(int position, Bitmap bmp) when finished to update the bitmapList and replace the placeholder
        textView.setText(drink.getName());

        if (subItems != null && subItems.contains(drink)) {
            textView.setVisibility(View.VISIBLE);
            imageView.setVisibility(View.VISIBLE);
        } else {
            textView.setVisibility(View.GONE);
            imageView.setVisibility(View.GONE);
        }
    }
    return v;
}

这篇关于Listview 显示错误的图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆