Я пытаюсь добавить изображения в ListView с ArrayAdapter. К вашему сведению, toList() — это преобразование итератора в список данного объекта DBObject.
Я переопределяю View getView()
и устанавливаю текстовое представление и изображение.
private static class EventAdapter extends ArrayAdapter<DBObject> {
public EventAdapter(Context context, int resource, Iterable<DBObject> events) {
super(context, resource, toList(events));
}
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
LayoutInflater vi = LayoutInflater.from(getContext());
v = vi.inflate(R.layout.adapter_event_list, null);
DBObject event = getItem(position);
if (event != null) {
//Get the logo if any
if( ((DBObject)event.get("events")).containsField("logo") ){
String logoURL = ((DBObject)((DBObject)event.get("events")).get("logo")).get("0").toString();
ImageView eventLogo = (ImageView) v.findViewById(R.id.eventLogoList);
new setLogo().execute(logoURL, eventLogo);
}
TextView title= (TextView) v.findViewById(R.id.eventTitleList);
title.setText( ((DBObject)event.get("events")).get("title").toString() );
}
return v;
}
protected static <T> List<T> toList( Iterable<T> objects ) {
final ArrayList<T> list = new ArrayList<T>();
for( T t : objects ) list.add(t);
return list;
}
//setLogo() method here. See below
}
Текст в textview в порядке. Однако изображения портятся. Кажется, они загружаются в неправильных местах в списке. Маршрут кода: 1) Получить из БД (асинхронно) 2) заполнить ListView 3) при заполнении загрузить каждое изображение (второй асинхронно).
Вот setLogo()
AsyncTask, который находится внутри EventAdapter
выше:
private class setLogo extends AsyncTask<Object,Void,Bitmap>{
ImageView eventLogo = null;
@Override
protected Bitmap doInBackground(Object...params) {
try{
Bitmap eventImage = downloadBitmap((String) params[0]);
eventLogo = (ImageView) params[1];
return eventImage;
}
catch(Exception e){
e.printStackTrace();
return null;
}
}
@Override
protected void onPostExecute(Bitmap eventImage) {
if(eventImage!=null && eventLogo!=null){
eventLogo.setImageBitmap(eventImage);
}
}
}
Я сделал это (используя асинхронный), который, как мне кажется, является правильным способом загрузки изображений с URL-адресов. Я видел этот пост о многопоточности, из которого я позаимствовал метод downloadBitmap()
.
Как объяснялось выше, изображения загружаются в неправильных местах ListView. Что может быть надежным способом их загрузки?
Также идея передать v.findViewById(R.id.eventLogoList)
внутри AsyncTask заключается в том, что программа будет различать ImageView каждого адаптера, но, похоже, это не так.
Обновить
После изучения проблемы, вызывающей этот микс, я нашел этот вопрос SO.
Я изменил свой код, чтобы проверить, не вызывает ли проблема if
.
//Get the logo if any
if( ((DBObject)event.get("events")).containsField("logo") ){
String logoURL = ((DBObject)((DBObject)event.get("events")).get("logo")).get("0").toString();
ImageView eventLogo = (ImageView) row.findViewById(R.id.eventLogoList);
//new setLogo().execute(logoURL, eventLogo);
TextView title= (TextView) row.findViewById(R.id.eventTitleList);
title.setText( "Shit happens" );
}
Допустим, у меня есть 40 предметов. Shit happens
устанавливается для полей, в которых существует поле logo
. Если я прокручиваю вниз/вверх, порядок меняется, и текст искажается. Это потому, что стек, созданный внутри цикла, меньше максимума списка.. Я думаю... Я все еще борюсь.
PS: я нашел эту простую библиотеку для асинхронной загрузки изображений вместо DYI.
Обновление 2
Я добавил else со статическим URL. Из-за времени, которое требуется для загрузки изображения, они все еще неуместны.