Загрузить растровые изображения/изображения в адаптер ListView

Я пытаюсь добавить изображения в 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. Из-за времени, которое требуется для загрузки изображения, они все еще неуместны.


person Diolor    schedule 21.01.2014    source источник


Ответы (1)


Я бы действительно пошел за хорошей библиотекой, такой как Пикассо. Он справится со всей сложной частью за вас, и он очень хорошо написан. http://square.github.io/picasso/

person Pasquale Anatriello    schedule 22.01.2014
comment
Спасибо за библиотеку, я попробовал, но содержимое все еще перепутано. - person Diolor; 22.01.2014