2

I'm trying to add images in a ListView which has an ArrayAdapter. Fyi, the toList() is a conversion from iterator to a list of the given DBObject.

I override the View getView() and set a textview and an image.

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
 }

The text in the textview is fine. However the images are getting messed up. They seem to load in wrong places in the list. The route of the code is: 1)Get from the DB (async) 2)populate the ListView 3) while populating load each image(second async).

Here is the setLogo() AsyncTask which is inside the EventAdapter above:

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);
            }
        }  

}

I did so (using an Async) which I believe is the correct way to load images from urls. I saw this post on multithreading and from which I borrowed the downloadBitmap() method.

As explained above the images are loaded in wrong places of the ListView. What can be a robust way to load them?

Also the idea to pass the v.findViewById(R.id.eventLogoList) inside the AsyncTask is that the program will distinguish each adapter's ImageView but it seems it doesn't.


Update

After following the problem that is causing this mix I found this SO question.

I altered my code in order to check if the if is causing the problem.

//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" );    

    }

Let's say I have 40 items. The Shit happens is set on the fields that a logo field exists. If I scroll down/up the order changes and the text gets messed up. It is because the stack created inside the loop is small than the maximum of the list..I guess... I am still struggling.

PS: I found this easy library to load images asynchronously instead of DYI stuff.


Update 2

I added an else with a static url. Because of the time it take to the image to load they are still misplaced.

Community
  • 1
  • 1
Diolor
  • 13,181
  • 30
  • 111
  • 179

1 Answers1

0

I would really go for a good library like Picasso. It will handle all the hard part for you and it's very well written. http://square.github.io/picasso/

Pasquale Anatriello
  • 2,355
  • 1
  • 16
  • 16