#android #listview #scroll #lazy-loading
#Android #listview #прокрутка #отложенная загрузка
Вопрос:
Моя проблема связана с тем, что пользователь прокручивает ListView. Я огляделся и увидел многочисленные примеры «listview lazy image», также посмотрел видео Google IO, в котором говорится о «хорошей практике» для выполнения этой работы. Но моя проблема сохраняется, когда пользователь перемещается вверх и вниз по ListView.
Что происходит, так это то, что при прокрутке списка изображения, которые были загружены для каждого элемента, перетасовываются, и аватар каждого элемента, переходящий к следующему элементу, заканчивается. Я не знаю, ясно ли я выражаюсь, но я покажу с изображением.
При запуске элементы, у которых нет изображения, остаются со стандартным изображением.
Изображение 1: http://boxandroid.com/app/weguide/itsok.png Перед тем, как пользователь прокручивает ListView: http://boxandroid.com/app/weguide/nook.png
Обратите внимание, что изображения были перетасованы среди других элементов.
в моем адаптере:
public View getView(int position, View convertView, ViewGroup parent){
ViewHolder viewHolder = new ViewHolder();
if(convertView == null){
convertView = _inflate.inflate(R.layout.layout_list, null);
viewHolder.text = (TextView) convertView.findViewById(R.id.title);
viewHolder.owner = (TextView) convertView.findViewById(R.id.owner);
viewHolder.image = (ImageView) convertView.findViewById(R.id.thumb);
convertView.setTag(viewHolder);
}else{
viewHolder = (ViewHolder) convertView.getTag();
}
HashMap<String, String> item = (HashMap<String, String>) getItem(position);
viewHolder.text.setText( item.get("poiName").toString() );
viewHolder.owner.setText( item.get("owner").toString() );
ImageView imageView = viewHolder.image;
imageView.setTag(item.get("thumbs"));
if(!item.get("thumbs").equals("null")){
Drawable cacheImage = loader.loadDrawable(item.get("thumbs"), new ImageManage.ImageCallback() {
public void imageLoaded(Drawable imageDrawable, String imageUrl) {
ImageView imageViewByTag = (ImageView) _listView.findViewWithTag(imageUrl);
if(imageViewByTag != null)
imageViewByTag.setBackgroundDrawable(imageDrawable);
}
});
imageView.setImageDrawable(cacheImage);
notifyDataSetChanged();
}
return convertView;
}
Комментарии:
1. Если возможно, опубликуйте некоторый исходный код, также показывающий, что на самом деле вы делаете..
Ответ №1:
За основу взят пример из блога Android.
http://android-developers.blogspot.com/2010/07/multithreading-for-performance.html
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder viewHolder = new ViewHolder();
if(convertView == null){
convertView = _inflate.inflate(R.layout.layout_list, null);
viewHolder.text = (TextView) convertView.findViewById(R.id.title);
viewHolder.owner = (TextView) convertView.findViewById(R.id.owner);
viewHolder.image = (ImageView) convertView.findViewById(R.id.thumb);
convertView.setTag(viewHolder);
}else{
viewHolder = (ViewHolder) convertView.getTag();
}
HashMap<String, String> item = (HashMap<String, String>) getItem(position);
viewHolder.text.setText( item.get("poiName").toString() );
viewHolder.owner.setText( item.get("owner").toString() );
viewHolder.image.setTag(item.get("thumbs"));
imageDowload.download(item.get("thumbs"), viewHolder.image);
return convertView;
}
теперь работает, спасибо.
Ответ №2:
Ваша проблема в том, что вы сопоставляете notifyDataSetChange() внутри метода getView
if(!item.get("thumbs").equals("null")){
Drawable cacheImage = loader.loadDrawable(item.get("thumbs"), new ImageManage.ImageCallback() {
public void imageLoaded(Drawable imageDrawable, String imageUrl) {
ImageView imageViewByTag = (ImageView) _listView.findViewWithTag(imageUrl);
if(imageViewByTag != null)
imageViewByTag.setBackgroundDrawable(imageDrawable);
}
});
imageView.setImageDrawable(cacheImage);
notifyDataSetChanged();
}
приведенный выше код должен быть выполнен вне метода getView.
Комментарии:
1. Я внедрил локальный кэш и изменил способ загрузки изображений. Я удалил функцию notifyDataSetChanged (), которая также теперь загружает изображения и использует кеш. Моя проблема также использовалась при прокрутке в listview. Спасибо. Извините, мой английский непонятен.
2. Ты молодец, мой друг, я пытался справиться с этим несколько дней, я решил это с помощью кэширования, но на устройствах низкого уровня я снова столкнулся с тем, что изображения перетасовывались, причина заключалась в том, что я проверял кэшированные изображения с помощью AsyncTask в методе doInBackground. Удаление этого кода решило мою проблему. 1