Ленивая загрузка изображений в ListView на Android - PullRequest
6 голосов
/ 22 сентября 2010

Я реализовал ленивую загрузку изображений в моем ListView. Я использую AsyncTask, чтобы загрузить изображение из Интернета и привязать его к ImageView в UIThread.

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

Полагаю, проблема в повторном использовании convertView в BaseAdapter. Любые идеи, чтобы решить это?

Большое спасибо.

EDIT: Я выкладываю ответ следующим образом:

public void setBitmap(int position, Bitmap image) {
    View itemView = mListView.getChildAt(position - mListView.getFirstVisiblePosition());
    if (itemView != null) {
        ImageView itemImageView = (ImageView) itemView.findViewById(R.id.item_imageview);
        itemImageView.setImageBitmap(image);
    }
}

Ответы [ 2 ]

7 голосов
/ 22 сентября 2010

Во время отложенной загрузки изображений в ListView возникают две проблемы.

  1. Старые изображения по-прежнему отображаются до тех пор, пока не будут загружены новые.Это легко, просто установите ImageView на изображение при загрузке или установите его как невидимое перед началом загрузки изображения.
  2. Вторая проблема сложнее решить.Представьте, что вы очень быстро прокручиваете свой список.Теперь ваши представления могут быть переработаны до того, как старый AsyncTask завершит загрузку изображения.Теперь у вас есть две запущенные задачи, которые в методе onPostExecute установят изображение для изображения.Теперь на короткое время неправильное изображение будет отображаться до завершения второго задания, или, что еще хуже, по какой-то причине, связанной с сетью, они не завершают работу в том порядке, в котором они начались, и у вас неправильное изображение, перезаписывает правильное изображение.Чтобы решить эту проблему, вы должны проверить, какое изображение должно отображаться после завершения задачи.В классе View есть два метода для таких вещей, как этот:

    setTag и getTag Вы можете привязать любой объект к представлению изображения, которое приходит вам в голову.В большинстве случаев я использую setTag, чтобы связать URL-адрес изображения в виде строки с изображением, прежде чем запускать задачу.Теперь я могу привести getTag к строке после выполнения задачи, сравнить URL-адрес, который должен отображаться, с URL-адресом, который я скачал, и установить изображение только при необходимости.

2 голосов
/ 22 сентября 2010

Создайте функцию с именем void setBitmap(Bitmap bitmap, int position) или похожую в вашем адаптере.Позвольте вашему AsyncTask вызывать этот метод, когда доступно новое растровое изображение.Этот метод может затем вызвать notifyDataSetChanged() в самом UI-потоке, чтобы обеспечить обновление представлений.Хранение ссылок на представления в адаптере (даже если они хранятся в AsyncTask) опасно!

...