@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
,它正在加载的 url 与新行数据相同。在这种情况下,您无需执行任何操作,因为它已经在加载您所追求的图像。
- 有一个
ImageContainer
但它正在加载的 url 与新的行数据不同。在这种情况下,取消请求并为当前行数据创建一个新的请求。
如果您愿意,您可以通过BaseAdapter
实现扩展来移动其中的一些逻辑AbsListView.RecyclerListener
(并将适配器设置为ListView
or的回收器侦听器GridView
)。该onMovedToScrapHeap(View view)
方法在刚刚被回收的视图中传递,这意味着您可以在其中取消任何挂起的图像请求。