0

I have a custom list view with an image. I need to set the source of the image via a url but I don't want the process to block the UI so I'm using an Async task. However the images are being set on only one image on the list and it shows up like a slideshow.

Is there a better way to go about this?

Here is my code:

Custom Adapter

class MyArrayAdapter extends ArrayAdapter<String> {

    private final Context context;
    private int i = 0;
    Contact[] myContact;
    String imageURL;

    public MyArrayAdapter(Context context, Contact[] contact) {
        super(context, R.layout.custom_list);
        this.context = context;
        this.myContact = contact;
        int s = myContact.length;
        int k = contact.length;
    }

    @Override
       public int getCount() {
           return myContact.length;
       }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        rowView = inflater.inflate(R.layout.custom_list, parent, false);
        TextView contact_first_name = (TextView) rowView
                .findViewById(R.id.first_name);
        TextView contact_last_name = (TextView) rowView
                .findViewById(R.id.last_name);
        imageView = (ImageView) rowView.findViewById(R.id.photo);
        imageURL = myContact[i].getImageUrl();          
        new LoadImageTask().execute(imageURL);

        contact_first_name.setText(myContact[i].getFirstName());
        contact_last_name.setText(myContact[i].getLastName());

        i++;

        return rowView;
    }       
}

Async Task

public class LoadImageTask extends AsyncTask<String, Integer, String> {

    Bitmap bitmap;

    @Override
    protected String doInBackground(String... imageURL) {
        // TODO Auto-generated method stub
        try {
              bitmap = BitmapFactory.decodeStream((InputStream)new URL(imageURL[0]).getContent());

            } catch (MalformedURLException e) {
              e.printStackTrace();
            } catch (IOException e) {
              e.printStackTrace();
            }
        return null;
    }

    protected void onPostExecute(String line) {

        try {
            imageView.setImageBitmap(bitmap);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
Amanni
  • 1,924
  • 6
  • 31
  • 51
  • There is more to this concept, imagine fling scrolling where the row disappears before the image has been downloaded... Read over this: [How do I do a lazy load of images in ListView](http://stackoverflow.com/q/541966/1267661) – Sam Dec 03 '12 at 00:25
  • Why do you think that loading the images would block the UI? Where are they stored? – Squonk Dec 03 '12 at 00:26
  • @squonk I just get them from different websites – Amanni Dec 03 '12 at 00:49

1 Answers1

0

Pass the imageview object when executing.
Use setTag to pass the url. The following will fix your problem, but I advised you to a good look at this tutorial. It will prevent you having out of memory and performances problems.

  @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        LayoutInflater inflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        rowView = inflater.inflate(R.layout.custom_list, parent, false);
        TextView contact_first_name = (TextView) rowView
                .findViewById(R.id.first_name);
        TextView contact_last_name = (TextView) rowView
                .findViewById(R.id.last_name);
        imageView = (ImageView) rowView.findViewById(R.id.photo);
        imageURL = myContact[i].getImageUrl();
        imageView.setTag(imageURL);    // add this      
        new LoadImageTask().execute(imageView); // change here

        contact_first_name.setText(myContact[i].getFirstName());
        contact_last_name.setText(myContact[i].getLastName());

        i++;

        return rowView;
    }   

In the async task:

public class LoadImageTask extends AsyncTask<ImageView, Integer, String> { // change here

    Bitmap bitmap;
   ImageView image = null; // add this

    @Override
    protected String doInBackground(String... imageURL) {
        // TODO Auto-generated method stub
    this.image = imageURL[0]; // add this
        String url = (String) image.getTag(); // add this

        try {
              bitmap = BitmapFactory.decodeStream((InputStream)new URL(url).getContent()); // change here

            } catch (MalformedURLException e) {
              e.printStackTrace();
            } catch (IOException e) {
              e.printStackTrace();
            }
        return null;
    }

    protected void onPostExecute(String line) {

        try {
            image.setImageBitmap(bitmap); // change here
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

This will fix your problem.

Lazy Ninja
  • 22,342
  • 9
  • 83
  • 103