Android Volley - 取消 Base Adapter 中的 NetworkImageView 请求

标签 android android-volley

正如标题所说,我正在使用 BaseAdapter 在 ListView 中显示项目。显然,ListView 会重用 View ,包括 TextView 和 NetworkImageView。

假设可以一次显示 3 个项目,NetworkImageView 将被重新用于索引处的项目:1, 4, 7, ....

根据显示的内容,NetworkImageView 将:

  1. 从网络请求图像并显示它,
  2. 显示缓存的位图,
  3. 或显示本地可绘制资源。

项目 2 和 3 工作正常,但是在场景 1 中,假设我们正在显示来自网络的索引 4 处的项目,并且用户在加载 4 之前滚动到项目 7,并且它是本地资源,我们显示本地资源。然而,我们的网络图像请求现在可能刚刚完成,所以我们最终显示了不正确的图像。

我怎样才能执行正确的(预期的)行为?

最佳答案

@Snicolas 的回答很准确,但缺少一些关于如何实际完成的指示。就这样吧。

总体思路是跟踪每一行正在进行的图像请求。这样,当您遇到回收行时,您可以取消挂起的请求并为与该行相关的新数据启动一个新请求。

实现此目的的一种直接方法是制作请求图像加载时可以返回的 ImageContainer,它是适配器的 ViewHolder/RowWrapper 的一部分。如果您还没有使用这种模式,您应该这样做。有很多例子,包括一个很好的 I/O 演讲。

一旦您将 ImageContainer 添加到您的 holder,请发出图像请求并存储您返回的容器。有点像这样:

ImageListener listener = ImageLoader.getImageListener(holder.imageview, defaultImageResId, errorImageResId);
holder.mImageContainer = ImageLoader.get(url, listener);

下次回收的行出现在适配器的 getView() 方法中时,您可以从它那里取回您的 holder 并检查它是否设置了 ImageContainer。以下 3 种情况之一可能适用:

  • 没有 ImageContainer,这意味着您可以发出新的图像请求。
  • 有一个 ImageContainer,它加载的 url 与新行数据的 url 相同。在这种情况下,您无需执行任何操作,因为它已经加载了您需要的图像。
  • 有一个 ImageContainer,但它加载的 url 与新行数据不同。在这种情况下,取消请求并为当前行数据重新请求。

如果您愿意,可以通过让您的BaseAdapter 扩展实现来移动其中的一些逻辑AbsListView.RecyclerListener (并将适配器设置为 ListViewGridView 的回收器监听器)。 onMovedToScrapHeap(View view) 方法在刚刚回收的 View 中传递,这意味着您可以取消其中任何待处理的图像请求。

关于Android Volley - 取消 Base Adapter 中的 NetworkImageView 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18302831/

相关文章:

java - 如何从 URL 加载图像到 Java Android?代码没有错误,但是不起作用

android - eclipse +安卓+Cocos2d-x : Why does the emulation only work once?

java - 构建安卓应用 :I can sending data to database in localhost but not the same in online database

android - 如何设置 Artifactory 使用 https ://maven. google.com 作为远程仓库?

尝试在另一个类中添加 ImageView 时,Android 应用程序崩溃

Android:如何直接从 Gmail 应用程序返回到应用程序的主屏幕?

java - 使用 Volley 向 PHP 脚本发送 POST 请求

android-volley - 具有不同 POST 请求的 Android Volley 缓存

android volley 会自动调整大图像的大小(子样本)

java - 如果 get volley 请求为 true,则需要从 cardview 中的可绘制对象更新图像(200 ok)