I have used an AsyncTask class to download and load images in listview asynchronously. But I have facing a problem which is the images of each row in the listvew will change continuously. Can anyone tell how to solve this problem and set the images to the right row position after loading?
ImageDownloaderTask class (AsyncTask)
class ImageDownloaderTask extends AsyncTask<String, Void, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
public ImageDownloaderTask(ImageView imageView) {
imageViewReference = new WeakReference<ImageView>(imageView);
}
@Override
// Actual download method, run in the task thread
protected Bitmap doInBackground(String... params) {
// params comes from the execute() call: params[0] is the url.
return downloadBitmap(params[0]);
}
@Override
// Once the image is downloaded, associates it to the imageView
protected void onPostExecute(Bitmap bitmap) {
if (isCancelled()) {
bitmap = null;
}
if (imageViewReference != null) {
ImageView imageView = imageViewReference.get();
if (imageView != null) {
if (bitmap != null) {
imageView.setImageBitmap(bitmap);
} else {
imageView.setImageDrawable(imageView.getContext().getResources()
.getDrawable(R.drawable.placeholder_gaan));
}
}
}
}
static Bitmap downloadBitmap(String url) {
final AndroidHttpClient client = AndroidHttpClient.newInstance("Android");
final HttpGet getRequest = new HttpGet(url);
try {
HttpResponse response = client.execute(getRequest);
final int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != HttpStatus.SC_OK) {
Log.w("ImageDownloader", "Error " + statusCode
+ " while retrieving bitmap from " + url);
return null;
}
final HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream inputStream = null;
try {
inputStream = entity.getContent();
final Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
return bitmap;
} finally {
if (inputStream != null) {
inputStream.close();
}
entity.consumeContent();
}
}
} catch (Exception e) {
// Could provide a more explicit error message for IOException or
// IllegalStateException
getRequest.abort();
Log.w("ImageDownloader", "Error while retrieving bitmap from " + url);
} finally {
if (client != null) {
client.close();
}
}
return null;
}
}
Adapter class
public class MenuAdapter extends ArrayAdapter<ItemRow> {
Context context;
public MenuAdapter(Context context, int resourceId,
List<ItemRow> items) {
super(context, resourceId, items);
this.context = context;
}
/*private view holder class*/
private class ViewHolder {
TextView txtTitle;
TextView txtBengTitle;
TextView txtArtist;
TextView txtTotalSongs;
ImageView thumbImage;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
ItemRow rowItem = getItem(position);
LayoutInflater mInflater = (LayoutInflater) context
.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
if (convertView == null) {
convertView = mInflater.inflate(R.layout.item_row, null);
holder = new ViewHolder();
holder.txtTitle = (TextView) convertView.findViewById(R.id.title);
holder.txtBengTitle = (TextView) convertView.findViewById(R.id.bengaliTitle);
holder.thumbImage = (ImageView) convertView.findViewById(R.id.thumbAlbum);
holder.txtArtist = (TextView) convertView.findViewById(R.id.artist);
holder.txtTotalSongs = (TextView) convertView.findViewById(R.id.totalSongs);
convertView.setTag(holder);
} else
holder = (ViewHolder) convertView.getTag();
holder.txtTitle.setText(rowItem.getTitle());
holder.txtBengTitle.setText(rowItem.getBengaliTitle());
holder.txtArtist.setText(rowItem.getArtist());
holder.txtTotalSongs.setText(rowItem.getTotalSongs());
String imageUrl = rowItem.getImage();
if (holder.thumbImage != null) {
new ImageDownloaderTask(holder.thumbImage).execute(imageUrl);
}
return convertView;
}
}
It is called lazy loading of images, this is quite small problem. Solutions are here: