发布延迟加载图像到ListView中

这是一种非常常见的情况:在ListView中显示必须从互联网上下载的图像。

现在我有一个用于ListView的ArrayAdapter自定义子类。 在ArrayAdapter的getView()实现中,我生成了一个单独的线程来加载图像。 加载完成后,它会查找合适的ImageView并使用ImageView.setImageDrawable()设置图像。 所以我使用的解决方案与此类似:在ListView中延迟加载图像

我遇到的问题是,只要我在ImageView上调用setImageDrawable(),ListView就会刷新列表中所有当前可见的行! 这导致了一种无限循环:

  • 调用getView()
  • 线程被派生成加载图像
  • 图像加载; 在ImageView上调用setImageDrawable()
  • ListView会因为某种原因而撷取它并自我刷新
  • 为了刷新ListView,为每个可见行调用getView(),所以我们回到步骤1,整个事情重复自己
  • 因此,据我所见,“Android - 我如何在ListView中执行延迟加载的图像”(请参阅​​上面的链接)中提出的解决方案根本无法工作。 它可能看起来像它,但它会运行得非常慢,因为在后台,它会不断重新加载当前可见的行。

    有没有人遇到过和/或有解决方案吗?


    在链接解决方案中,如果视图尚未具有正确的drawable, fetchDrawableOnThread()应调用fetchDrawableOnThread()

    如果getDrawable()返回null,则视图不具有可绘制的。

    如果您重复使用插槽,您认为您需要进一步管理状态。 例如,如果你的视图有一个存储URL的成员变量,并且是一个表示是否加载的布尔值,那么很容易知道是否调用fetchDrawableOnThread()

    我推测drawable的toString()详细说明了图像加载的路径。 (如果没有,你可以将返回的drawable子类化)。 在这种情况下,您可以避免上面概述的布尔值,只是做一个比较来确定它是否可以右键绘制或者是否获取替换。

    此外,可视行上的getView()应确保那些不再可见的行被卸载,以防内存耗尽。 一个技巧就是将不再可见的图像移动到软引用(因此当需要内存时它们被卸载),作为另一张原始线程上的海报。


    我在下面的链接中使用了代码:另一个stackoverflow问题

    为了解决回收视图问题,我做了一些小改动。我将image的url设置为适配器中imageview的Tag。 以下代码包含解决回收问题的解决方案:

    public void fetchDrawableOnThread(final String urlString, final ImageView imageView,Drawable drw) {
    
        imageView.setImageDrawable(drw);//drw is default image
        if (drawableMap.containsKey(urlString)) {
            if(imageView.getTag().toString().equals(urlString))
            {
                imageView.setImageBitmap(drawableMap.get(urlString));
                imageView.invalidate();
                return;
            }
    
        }
    
        final Handler handler = new Handler() {
            @Override
            public void handleMessage(Message message) {
                BitmapWrapper wrapper = (BitmapWrapper)message.obj;
                if(wrapper.imageurl.equals(imageView.getTag().toString()))
                {
                    imageView.setImageBitmap((Bitmap)wrapper.bitmap);
                    imageView.invalidate();
                }
    
            }
        };
    
        Thread thread = new Thread() {
            @Override
            public void run() {
                //TODO : set imageView to a "pending" image
    
                Bitmap drawable = fetchDrawable(urlString);
                BitmapWrapper wrapper = new BitmapWrapper();
                wrapper.bitmap = drawable;
                wrapper.imageurl = urlString;
                Message message = handler.obtainMessage(1, wrapper);
                handler.sendMessage(message);
            }
        };
        thread.start();
    }
    
    
        public class BitmapWrapper
    {
        public Bitmap bitmap;
        public String imageurl;
    }
    

    我遇到过同样的问题。

    经过近2天的大量调试/优化并试图弄清楚,为什么在getView()使用setImageBitmap()时,我的getView()被一遍又一遍地调用,我提出了一个肮脏的解决方案:

    1)扩展您用于列表中所有图像的自定义ImageView

    2)在此ImageView覆盖该方法

    @Override
    public void requestLayout()
    { 
      return; 
    }
    

    3)脏,但对我来说,它的工作

    4)利润;)

    链接地址: http://www.djcxy.com/p/93115.html

    上一篇: Issue with lazy loading images into a ListView

    下一篇: How to display a list of images in a ListView in Android?