Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android listview数据图像在快速向下滚动时重复_Android_Image_Android Listview - Fatal编程技术网

Android listview数据图像在快速向下滚动时重复

Android listview数据图像在快速向下滚动时重复,android,image,android-listview,Android,Image,Android Listview,我有一个适配器,可以从internet加载数据。如果我快速向下滚动,它会在显示正确图像之前的一瞬间显示错误图像。但是,图像旁边的相应文本不会执行此操作。当它动态下载更多数据时,这一点就更加明显了。请帮我调试这个。以下是listview的外观: categoryAdapter使用仅包含textview数据的数据列表初始化。调用categoryAdapter的getView()时,它会通过asynctask从url下载图像。当到达listview的底部时,OnScrollListener会再下载1

我有一个适配器,可以从internet加载数据。如果我快速向下滚动,它会在显示正确图像之前的一瞬间显示错误图像。但是,图像旁边的相应文本不会执行此操作。当它动态下载更多数据时,这一点就更加明显了。请帮我调试这个。以下是listview的外观:

categoryAdapter使用仅包含textview数据的数据列表初始化。调用categoryAdapter的getView()时,它会通过asynctask从url下载图像。当到达listview的底部时,OnScrollListener会再下载12篇文章(同样只下载文本)。下面是getView()。请注意,我认为回收旧视图是个问题,所以我尝试在将imageview的drawable更改为新图像之前快速将图像设置为null,这样我就不会看到旧图像。如果我快速向上滚动,但如果快速向下滚动,则不会看到错误。可能是什么问题

class CategoryAdapter extends BaseAdapter{...
@Override
public View getView(int i, View view, final ViewGroup viewGroup){
    // crate a new rowItem object here
    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View row;

    if (view == null) row = inflater.inflate(R.layout.single_row, viewGroup, false);
    else row = view;

    // Get the description, image and title of the row item
    TextView title = (TextView) row.findViewById(R.id.textView);
    TextView description = (TextView) row.findViewById(R.id.textView2);
    ImageView image = (ImageView) row.findViewById(R.id.imageView);
    ProgressBar pb = (ProgressBar) row.findViewById(R.id.progressBarSingleRow);

    /* On getting view, set this to invisible until loaded. (issue before: old image seen
       before new image on fast scroll) Mostly fixed by this, but on fast scroll down, still
       shows a little */
    image.setImageDrawable(null);

    // Set the values of the rowItem
    SingleRow rowTemp = articles.get(i);
    title.setText(rowTemp.title);
    description.setText(rowTemp.description);

    String s = "null";
    if (rowTemp.image != null) s = "not null";
    Log.e("ImageLog", "Item " + Integer.toString(i) + ", is " + s);

    // Load image into row element
    if (rowTemp.image == null) {    // download
        // Prepare prepped row objects in single holder object for fetchCategoryImageTask
        AdapterObject holder = new AdapterObject();
        holder.title = title;
        holder.description = description;
        holder.image = image;
        holder.pb = pb;

        new FetchCategoryImageTask(rowTemp, holder).execute();
    }
    else {                          // set saved image
        // Cropping image to preserve aspect ratio
        image.setScaleType(ImageView.ScaleType.CENTER_CROP);
        image.setCropToPadding(true);
        image.setImageBitmap(rowTemp.image);
    }

    return row;
}
以防万一,这里有一些fetchCategoryImageTask()


这里发生的是ListView重用视图。因此,它可以重用已经有图像的视图。我建议您使用Volley库或ImageLoader库来解决此问题,在下载图像时很容易定义要显示的占位符

因此,不要使用Asynctask,而是使用以下代码:

private void showImage(View view, String imageUrl) {
        DisplayImageOptions options = new DisplayImageOptions.Builder()//
                .showImageOnFail(R.drawable.image_placeholder) 
                .showImageOnLoading(R.drawable.image_placeholder) 
                .showImageForEmptyUri(R.drawable.image_placeholder) 
                .cacheInMemory(true) 
                .cacheOnDisk(true) 
                .build();
        ImageLoader.getInstance().displayImage(imageUrl, imageViewType, options);
    }

通用图像加载器库:

这个答案来自评论,所以我将在这里发布。我将使用viewHolder模式,不必在每次使用LRU缓存获取行和缓存图像时查找视图。以下是参考链接:,。

在scroll上,android将继续调用重新创建listItem的适配器的getView方法,首先您应该尝试为listView正确使用ViewHolder模式,然后缓存图像,您可以查看android文档,了解如何实现LRucache我并不反对尝试,这听起来是一个很好的练习。我有很多图片,你觉得通用图片加载器怎么样?我认为asynctask以后可能会被替换(android教程告诉我,如果我改变手机方向,asynctask可能会被删除)。Universal ImageLoader库肯定会使用asynctask来获取图像,但如果您不愿意自己完成实现过程,那么使用它也不是一个坏主意。ImageLoader基本上为您处理所有问题,例如缓存。当屏幕方向改变时,活动被重新创建,但异步任务在后台运行,所以我真的看不到异步任务被删除。好的。我阅读,然后。你觉得磁盘缓存和软引用怎么样?嗯,我认为这是你的选择,实际上,这取决于你想要的缓存大小的最大内存。android文档表明不再推荐WeakReferences和SoftReferences。要从asynctask将图像下载到这里,需要对我的实现进行多少更改?这会比实现一个viewholder模式简单吗?我非常喜欢使用库,我认为这很容易。。。下面是设置内容的代码,如title.setText(rowTemp.title)、description.setText(rowTemp.description);您可以设置imageView和imageUrl。。。showImage(图像、图像URL)。
private void showImage(View view, String imageUrl) {
        DisplayImageOptions options = new DisplayImageOptions.Builder()//
                .showImageOnFail(R.drawable.image_placeholder) 
                .showImageOnLoading(R.drawable.image_placeholder) 
                .showImageForEmptyUri(R.drawable.image_placeholder) 
                .cacheInMemory(true) 
                .cacheOnDisk(true) 
                .build();
        ImageLoader.getInstance().displayImage(imageUrl, imageViewType, options);
    }