android listview 更新延迟,关于java:Android – 将图像延迟加载到ListView中的问题

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

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

我遇到的问题是,一旦我在ImageView上调用setImageDrawable(),ListView就会以某种方式刷新列表中所有当前可见的行!这会产生一种无限循环:

调用getView()

生成线程以加载图像

图像已加载;在ImageView上调用setImageDrawable()

ListView由于某种原因选择它并刷新自己

为了刷新ListView,为每个可见行调用getView(),所以我们回到第1步,整个过程重复

所以据我所知,"Android中如何在ListView中对图像进行延迟加载"(参见上面的链接)中提出的解决方案根本不起作用。它可能看起来像它,但它会运行得非常慢,因为在后台,它会不断重新加载当前可见的行。

之前是否有人遇到此问题和/或有解决方案?

我遇到过同样的问题。

经过近2天的大量调试/优化并试图弄明白,为什么我的getView()在一行中使用setImageBitmap()时一遍又一遍地调用所有视图,我想出了一个肮脏的解决方案:

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

2)在此ImageView中覆盖该方法

@Override

public void requestLayout()

{

return;

}

3)很脏,但对我来说它很有效

4)利润;)

如果列表上的图像大小相同,并且您的图像视图也是固定大小(不是换行内容),则可以使用它。 这对我有所帮助,谢谢:)

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

我做了一些小改动,以解决回收视图问题。我在适配器中将图像的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;

}

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

如果getDrawable()返回null,则视图没有drawable。

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

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

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

是的我正在使用地图来缓存图像。 但这没关系,因为我最终仍然调用setImageDrawable(),它再次触发刷新。 如果我能以某种方式禁用refesh它将解决我的问题。 我还没有使用SoftReferences(但我会),但这只是一个内存优化,这不解决无限循环

好的一点我误解了你的意思是线程产生加载图像。 生病了改写我的回答

感谢您的快速回复:)当您不重复使用视图来显示像我这样的行时,您现在描述的内容确实可以解决问题。 重用行我的意思是使用给getView()的"convertView"参数。 重用行视图时,您是否知道此解决方案? (因为在这种情况下你必须每次都调用setImageDrawable())

我有一个ThumbnailAdapter,它包含了可能有用的整个模式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值