2013-08-18 4 views
1

Как гласит название, я использую BaseAdapter для отображения элементов в ListView. Очевидно, ListView будет повторно использовать представления, включая TextViews и NetworkImageViews.Android Volley - Отмените запрос NetworkImageView в базовом адаптере

Предполагая 3 пунктов могут быть отображены сразу, NetworkImageView будет повторно использоваться для пунктов по индексу: 1, 4, 7, ....

В зависимости от того, что отображается, то NetworkImageView будет либо:

  1. запрос изображения из сети и отобразить его,
  2. дисплей кешированная Bitmap,
  3. или отобразить локальный Drawable ресурс.

Элементы 2 и 3 работают нормально, однако в Сценарии 1, скажем, мы показываем элемент по индексу 4 из сети, а пользователь прокручивает элемент 7 до загрузки 4 и является локальным ресурсом, мы отображение локального ресурса. Однако наш сетевой запрос на изображение может просто закончиться сейчас, поэтому в результате мы получим неправильное изображение.

Как я могу обеспечить соблюдение правильного (ожидаемого) поведения?

ответ

5

Ответ от @Snicolas - это место, но не хватает указателей на то, как это сделать. Так вот.

Общая идея состоит в том, чтобы отслеживать текущие запросы изображения для каждой строки. Таким образом, когда вы столкнетесь с переработанной строкой, вы можете отменить ожидающий запрос и запустить новый для новых данных, относящихся к этой строке.

Один простой способ сделать это, чтобы сделать ImageContainer, что вы можете получить обратно при запросе загрузки изображения, части ViewHolder/RowWrapper адаптера. Если вы еще не используете этот шаблон, вам следует. Много примеров там, в том числе хороший разговор ввода-вывода.

После того, как вы добавили 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 или GridView). Метод onMovedToScrapHeap(View view) передается в представлении, которое только что было переработано, что означает, что вы можете отменить любые ожидающие запросы изображения.

+0

@ Ответ Pork правильный, но это очень полезная информация, если вы не используете 'NetworkImageView'. Также хорошая информация об использовании 'AbsListView.RecyclerListener', если кто-то нуждается в дальнейшем контроле над представлениями. +1 – pjco

+0

Спасибо за ваш ответ, у меня есть только сомнения, как вы можете отменить запросы, сделанные с помощью метода get из ImageLoader? вы не можете добавить тег к этим запросам, что вам нужно, чтобы отменить запрос. – vantesllar

+0

Nevermind, я видел, что класс ImageContainer имеет свой собственный метод, чтобы отменить запрос, изображение которого предназначено для хранения. – vantesllar

-1

Я не знаю этого API, но я предполагаю, что вы должны отменить любой ожидающий запрос до повторного использования такого вида. Как вы можете это сделать, я не могу сказать.

ли вы здесь альтернатив, таких как:

3

Вам не нужно ничего принуждать, если вы используете предоставленный NetworkImageView.

NetworkImageView обнаруживает, когда он был переработан и автоматически отменяет запрос.

+0

К сожалению, это на самом деле не отвечает на вопрос. В адаптере для чего-то вроде ListView соответствующее представление перерабатывается, и поэтому оно никогда не будет отсоединено. – StackOverflowed

+0

NetworkImageView обнаруживает, когда он перерабатывается. –

+0

Можете ли вы показать мне, где это происходит, если вы не возражаете? Одна вещь с Volley заключается в том, что нет «релизов» или номеров версий, поэтому просто может быть, что я использую более старую версию. – StackOverflowed