UIL,Picasso - 当停止滚动时,适配器中的图像总是重新加载

11

我有一个带有文本和来自互联网的大图片的ListView。我的图片项目具有适合宽度和wrap_content高度。
我试图使用UILPicasso将图像显示为背景。 它们都可以工作,但当我停止滚动时,图像始终重新加载,使ListView闪烁
效果看起来像这样:

进入图像描述

您可以看到当我停止滚动时(向下滚动,然后向上滚动),它会重新加载已下载和缓存的图像
我该如何防止这种情况发生?

 <ImageView android:id="@+id/imgFeed"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:scaleType="centerCrop"/>

 // UIL
 options = new DisplayImageOptions.Builder()
 .showImageOnLoading(defaultImage)
 .showImageOnFail(defaultImage)
 .showImageForEmptyUri(defaultImage)
 .resetViewBeforeLoading(false)
 .cacheOnDisk(true).delayBeforeLoading(0)
 .displayer(new  FadeInBitmapDisplayer(200)).cacheInMemory(true).imageScaleType(ImageScaleType.EXACTLY_STRETCHED).build();

 ImageAware imageAware = new ImageViewAware(viewHolder.imgFeed, false); 
 ImageLoader.getInstance().displayImage(item.getPhotoUrl(), imageAware, options);

// Picasso
 Picasso.with(getContext())
                        .load(item.getPhotoUrl())
                        .placeholder(R.drawable.place_holder_big)
                        .resize(screenWidth, 0) //set max width
                        .into(viewHolder.imgFeed);

对于 UIL,我在这个问题中尝试了很多方法,但它们都无法为我工作。

更新:看起来我遇到了内存缓存问题,就像这个问题。但是我该如何解决这个问题?看看 Facebook 应用程序,他们做得非常好。所有图像的大小都不同,适合宽度,并且在不重新加载图像的情况下非常流畅地滚动。他们是如何做到的?


你测试的是哪个版本的安卓? - Anderson K
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Khushal Chouhan
@A.Anderson 看起来这个问题在所有的安卓版本上都出现了。我测试过安卓2.3、4.4和5.0。 - ductran
是的,你必须创建自己的小部件,虽然谷歌可以处理它,但需要强大的编程知识,而我并没有。我更愿意使用滚动视图和线性布局创建自己的小部件,它比列表适配器工作得更快。 - Khushal Chouhan
@CommonsWare 谢谢,我刚试了一下Fresco库,但是由于我的应用程序达到了65k方法限制,所以它无法在我的应用中工作,因为我的应用有很多库。问题是,如果我不像这样作弊,我就不能使它流畅运行吗?Google+和Twitter应用也作弊了吗?因为我看到它们有平滑的滚动。我认为应该有一种方法可以在不作弊的情况下实现它,而不会占用太多内存。 - ductran
显示剩余10条评论
2个回答

4
如果你想知道Facebook是如何做到的,实际上他们发布了他们的图像加载库(https://github.com/facebook/fresco)
在那个时间点,你是否真的在调用底层ListView的notifyDataSetChanged?同时,你是否在使用hasStableIds()?
对于UIL,你可以尝试使用WeakMemoryCache(参考https://github.com/nostra13/Android-Universal-Image-Loader/wiki/Useful-Info),这理论上允许您利用所有可用的内存,但可能会导致大量额外的GC调用。
对于Picasso,Taha的方法似乎是你最好的选择!

1
也许您的内存缓存大小较小,Picasso 尝试从磁盘缓存加载图像。请查看这里以确定缓存大小。您可以通过以下方式尝试增加 Picasso 的缓存大小:
Picasso p = new Picasso.Builder(context)
.memoryCache(new LruCache(cacheSize))
.build();

然而,在我看来,你的应用程序似乎拥有无尽的反馈。这意味着您的内存缓存将在某个时候变满,并且您将不得不使用磁盘缓存。与内存缓存相比,从磁盘缓存检索数据速度较慢。

我在UIL中同时使用了磁盘缓存和内存缓存,但这个问题仍然存在(实际上我还没有尝试过在Picasso上使用磁盘缓存,因为我不知道该怎么做)。但是你认为磁盘缓存会起作用吗? - ductran
我认为你需要一个更大的内存缓存,但最终你会使用磁盘缓存,这将导致一些延迟。增加缓存大小能解决这个问题吗?我不确定。也许问题是因为没有清除列表视图项所导致的。我的意思是清除视图,就像在回收视图中一样。 - Taha

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接