title: ImageView getting recycled by GridView
body: <p>I have a <code>GridView</code> which contains an <code>Adapter</code> which extends <code>ArrayAdapter&lt;Album&gt;</code> (Where Album is Album info got from LastFM API).</p>
  
  <p>The <code>Album</code> info comes with a URL to a image. I asynchronously download those images and put them in the <code>Adapter</code> along with the album name.</p>
  
  <p>However, when I scroll the <code>GridView</code> down and up, the rows get recycled. When I inflate them again, the images get swapped and I don't really know what's happening.</p>
  
  <p>I've tried storing the images in a <code>HashMap&lt;String, Bitmap&gt;</code> to no avail.</p>
  
  <p>Here's the code of my <code>Adapter</code></p>
  
  <pre><code>package com.gigtracker.adapter;
  
  import java.text.DecimalFormat;
  import java.util.Collection;
  import java.util.HashMap;
  import java.util.concurrent.CopyOnWriteArrayList;
  
  import android.annotation.SuppressLint;
  import android.app.Activity;
  import android.content.Context;
  import android.graphics.Bitmap;
  import android.os.AsyncTask;
  import android.util.TypedValue;
  import android.view.LayoutInflater;
  import android.view.View;
  import android.view.ViewGroup;
  import android.widget.ArrayAdapter;
  import android.widget.ImageView;
  import android.widget.TextView;
  
  import com.garli.lastfmapi.Album;
  import com.garli.lastfmapi.Artist;
  import com.garli.lastfmapi.ImageSize;
  import com.gigtracker.R;
  import com.gigtracker.utils.ImageDownloader;
  
  public class AlbumAdapter extends ArrayAdapter&lt;Album&gt; {
  
      private final ImageDownloader d;
      int playcount;
  
      @SuppressLint("UseSparseArrays")
      private final HashMap&lt;Integer, View&gt; map = new HashMap&lt;Integer, View&gt;();
  
      public AlbumAdapter(final Context ctx, final Artist artist) {
          super(ctx, 0);
          d = new ImageDownloader();
          new AsyncTask&lt;Void, Void, Void&gt;() {
              CopyOnWriteArrayList&lt;Album&gt; albums = new CopyOnWriteArrayList&lt;Album&gt;();
  
              @Override
              protected Void doInBackground(final Void... params) {
                  final Collection&lt;Album&gt; albumCollection = Artist
                          .getTopAlbums(artist.getName());
                  for (final Album album : albumCollection) {
                      if (playcount &lt; album.getPlaycount()) {
                          playcount = album.getPlaycount();
                      }
                      albums.add(album);
                  }
  
                  return null;
              }
  
              @Override
              protected void onPostExecute(final Void result) {
                  for (final Album album : albums) {
                      add(album);
                  }
                  notifyDataSetChanged();
              }
  
          }.execute();
      }
  
      @Override
      public View getView(final int position, View convertView,
              final ViewGroup parent) {
          final TextView tv, tv2;
          final ImageView iv;
          final Album album = getItem(position);
          if (map.get(Integer.valueOf(position)) == null) {
              if (convertView == null) {
                  convertView = LayoutInflater.from(getContext()).inflate(
                          R.layout.grid_item, null);
                  tv = (TextView) convertView.findViewById(R.id.textViewName);
                  iv = (ImageView) convertView.findViewById(R.id.imageView1);
                  tv2 = (TextView) convertView.findViewById(R.id.textViewRating);
                  @SuppressWarnings("deprecation")
                  int buttonDimension = ((Activity) getContext())
                  .getWindowManager().getDefaultDisplay().getWidth() / 2;
                  final int paddingTotal = (int) TypedValue.applyDimension(
                          TypedValue.COMPLEX_UNIT_DIP, 20, getContext()
                          .getResources().getDisplayMetrics());
                  buttonDimension -= paddingTotal;
                  iv.getLayoutParams().height = buttonDimension;
                  iv.getLayoutParams().width = buttonDimension;
                  new AsyncTask&lt;Void, Void, Void&gt;() {
                      Bitmap bmp;
  
                      @Override
                      protected Void doInBackground(final Void... params) {
                          bmp = d.downloadBitmap(album
                                  .getImageURL(ImageSize.LARGE));
                          return null;
                      }
  
                      @Override
                      protected void onPostExecute(final Void result) {
                          iv.setImageBitmap(bmp);
                      }
  
                  }.execute();
  
              } else {
                  tv = (TextView) convertView.findViewById(R.id.textViewName);
                  tv2 = (TextView) convertView.findViewById(R.id.textViewRating);
              }
          } else {
              convertView = map.get(Integer.valueOf(position));
              tv = (TextView) convertView.findViewById(R.id.textViewName);
              tv2 = (TextView) convertView.findViewById(R.id.textViewRating);
          }
          tv.setText(album.getName());
          final float percentage = 100 * (float) album.getPlaycount() / playcount;
          tv2.setText(new DecimalFormat("##0.00").format(percentage) + "%");
          if (percentage &gt;= 90) {
              tv2.setTextColor(0xff99ff33);
          } else if (percentage &gt;= 75) {
              tv2.setTextColor(0xffffff66);
          } else if (percentage &gt;= 50) {
              tv2.setTextColor(0xffff9900);
          } else if (percentage &gt;= 25) {
              tv2.setTextColor(0xffcc6600);
          } else {
              tv2.setTextColor(0xffcc0000);
          }
          return convertView;
      }
  }
  </code></pre>