【问题标题】:Android - Gridview images mixes on scrollAndroid - Gridview 图像在滚动时混合
【发布时间】:2013-04-24 07:08:08
【问题描述】:

我有一个显示两列图像视图的网格视图。我正在使用异步任务加载这些图像(请参阅这篇文章Lazy load of images in ListView

但是当我滚动 gridview 时,位置中的图像正在混合。例如第 14 张图像显示第 1 张图像,我认为视图试图在异步任务完成之前显示旧图像。

我的代码:

    public Content getItem(int position) {
        return contents.get(position);
    }

    public long getItemId(int position) {
        return position;
    }

    @Override 
    public boolean hasStableIds() { return true; }

    public View getView(int position, View convertView, ViewGroup parent) {
        Thumbnail contentView;
        Content current = contents.get(position);
        if (convertView == null) {
            contentView = new Thumbnail(mContext);  
        }
        else {
            contentView = (Thumbnail) convertView;
        }

        contentView.title = current.getTitle();
        contentView.image = current.getImage();
        contentView.link = current.getLink();
        contentView.init();

        return contentView;
    }

初始化函数

    TextView titleText = (TextView)super.findViewById(R.id.titleText);
    titleText.setText(title);

    ImageView imageControl = (ImageView)super.findViewById(R.id.thumbImage);
    DrawableManager loadImage = new DrawableManager();              loadImage.fetchDrawableOnThread(imgUrl, imageControl);

等待您的帮助

谢谢

【问题讨论】:

    标签: android image object gridview


    【解决方案1】:

    这是由于资源重用而发生的。你应该做什么:

    1. 首先,只需在 getView 方法中为您的 imageView (contentView.image.setImageResource(DEFAULT_RESOURCE)) 设置某种默认图片(过渡默认图片总比错误图片好)。

    2. 为您的图片设置唯一标签,例如要加载的图片的位置或网址 (contentView.image.setTag(url))。 当 AsyncTask 完成时,您可以使用一些检查,例如

      String url=(String)imageView.getTag();
      
      if (url.equals(mUrl)) { //mUrl can be transmitted to AsyncTask instance separately
          mActivity.runOnUiThread(new Runnable() {
      
          @Override
          public void run() {
              imageView.setImageDrawable(bmp);
          });
      });
      }
      

    之所以需要它,是因为 Adapter 不会为所有 N 个 ImageView 分配内存用于 N 个项目。它只存储可见项目和一些保留的 ImageView 所需的数量。因此,无法保证您存储的 ImageView 引用将在几秒钟内成为实际引用,因为它可能变得不可见并被可见的引用重复使用。

    【讨论】:

    • 添加了这一行。但什么都没有改变。它显示旧图像并在异步任务完成时更改为新图像。它有时也会显示错误的图像。我认为异步任务指向错误的图像控制。还尝试将标签设置为 imageview。
    • 是的,这也可能因为视图重用而发生(例如,由于流过屏幕边缘而变得不可见的 ImageView 可以重用于具有相同内存指针的可见视图)。但是设置标签肯定会帮助你(并且帮助了我好几次)。
    • 设置 url 标签并将标签与 url 字符串进行比较对我有用 :) 非常感谢 Andrei。真的很头疼
    • 很高兴为您提供帮助,请按“接受”按钮 :)
    【解决方案2】:

    不要自己加载图像。使用 Universal Image Loader 。它可以缓存、图像和加载的位图。让你的问题消失。它还支持显示存根图像和滚动自动暂停等。

    如果您重用它,它只为 imageView 的最后一个实例加载图像,从而解决您的特定问题。

    imageLoader.displayImage(imageUri, imageView);
    

    这就是异步加载图像所需的全部内容。

    【讨论】:

    • 我正在使用 DrawableManager.. 见第 2 篇文章。 stackoverflow.com/questions/541966/…
    • 该帖子已有 3 年历史。世界变了。使用 UIL。只需进一步查看您发布的问题即可。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-05-19
    • 2018-06-14
    • 1970-01-01
    • 1970-01-01
    • 2013-01-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多