正如标题所说,我正在使用BaseAdapter在ListView中显示项目。显然,ListView将重用视图,包括TextViews和NetworkImageViews。
假设一次可以显示3个项目,NetworkImageView将重复用于索引的项目:1,4,7 ...... ....
根据显示的内容,NetworkImageView将:
第2项和第3项工作正常,但是在场景1中,假设我们正在从网络显示索引4处的项目,并且用户在加载4之前滚动到项目7并且它是本地资源,我们显示本地资源。但是我们的网络图像请求现在可能正在完成,因此我们最终会显示不正确的图像。
如何执行正确的(预期的)行为?
答案 0 :(得分:5)
@Snicolas的答案很明显,但缺乏关于如何实现这一目标的一些指示。所以这里。
一般的想法是跟踪每行的正在进行的图像请求。这样,当您遇到循环行时,您可以取消待处理的请求,并为与该行相关的新数据启动新请求。
实现这一目标的一种简单方法是,在请求图像加载时,使ImageContainer
成为适配器的ViewHolder / RowWrapper的一部分。如果你还没有使用这种模式,你应该这样做。那里有很多例子,包括一个很好的I / O谈话。
将ImageContainer
添加到持有者后,发出图片请求并存储您收到的容器。有点像这样:
ImageListener listener = ImageLoader.getImageListener(holder.imageview, defaultImageResId, errorImageResId);
holder.mImageContainer = ImageLoader.get(url, listener);
下一次使用适配器的getView()
方法中的循环行时,您可以让持有者从中恢复,并检查它是否设置了ImageContainer
。可能适用以下3种情况之一:
ImageContainer
,这意味着您可以去制作新的图像请求。ImageContainer
,它加载的网址与新行数据相同。在这种情况下,您不必执行任何操作,因为它已经加载了您之后的图像。ImageContainer
,但它加载的网址与新的行数据不同。在这种情况下,取消请求并为当前行数据创建一个新请求。如果您愿意,可以通过BaseAdapter
扩展程序实现AbsListView.RecyclerListener
来移动部分逻辑(并将适配器设置为ListView
或GridView
的回收者监听器)。 onMovedToScrapHeap(View view)
方法在刚刚被回收的视图中传递,这意味着您可以在那里取消任何待处理的图像请求。
答案 1 :(得分:3)
如果使用提供的NetworkImageView,则无需强制执行任何操作。
NetworkImageView会检测它何时被回收并自动取消请求。
答案 2 :(得分:-1)