Dec 20, 2011

Asynchronous ListView image and data loading in Android

Hi! Today I'm going to tell you how to load data in ListView items asynchronous in Android.
First. For example we'll build a list of images, that we download from the Internet.
Second. ListView item is the simple LinearLayout with ImageView.



     
   


Third. Our adapter code:
public class ImageListAdapter extends BaseAdapter {
 
 private List itemsUrls;
 private Context ctx;
 
 public FeedListAdapter(Context ctx) {
  this.ctx = ctx;
 }
 
 private class ViewHolder {
  public ImageView image;
  
 }

 @Override
 public int getCount() {
  return itemsUrls.size();
 }

 @Override
 public Status getItem(int pos) {
  return itemsUrls.get(pos);
 }

 @Override
 public long getItemId(int pos) {
  return pos;
 }

 @Override
 public View getView(int pos, View convertView, ViewGroup parent) {
  View v = convertView;
  if(v == null){
   LayoutInflater vi = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
   v = vi.inflate(R.layout.status_item, null);
   ViewHolder holder = new ViewHolder();
   holder.image = (ImageView) v.findViewById(R.id.image);
   v.setTag(holder);
  }
  ViewHolder holder = (ViewHolder)v.getTag();
  //Setting the image url as a tag for the image view
  holder.image.setTag(items.get(pos));
  holder.image.setImageDrawable(null);
  //starting async task for image loading
  new ImageTask().execute(holder);
  return v;
 }
 
 private class ImageTask extends AsyncTask {
  
  private ImageView avatarImage;
  private Bitmap av = null;
  private String url;
  
  @Override
  protected void onPostExecute(Boolean result) {
   super.onPostExecute(result);
   if(result && av != null) {
    if(avatarImage.getTag().toString().equals(url)) {
     avatarImage.setImageBitmap(av);
    }
   }
  }

  @Override
  protected Boolean doInBackground(ViewHolder... params) {
   ViewHolder item = (ViewHolder) params[0];
   boolean result = false;
   if(item != null) {
    try {
     avatarImage = item.image;
     url = item.image.getTag().toString();
     av = getBitmapMethod(url);
     result = true;
    } catch (Exception e) {
     e.printStackTrace();
    }
   }
   return result;
  }
  
 }
}

Here it is, now we have the async image loading as in different twitter clients.

No comments: