title: ListView not refreshing already-visible items
body: <p>I'm displaying a list of contacts (name + picture) using the <code>ListView</code>. In order to make the initial load fast, I only load the names first, and defer picture loading. Now, whenever my background thread finishes loading a picture, it schedules my adapter's <code>notifyDataSetChanged()</code> to be called on the UI thread. Unfortunately, when this happens the <code>ListView</code> does not re-render (i.e. call <code>getView()</code> for) the items that are already on-screen. Because of this, the user doesn't see the newly-loaded picture, unless they scroll away and back to the same set of items, so that the views get recycled. Some relevant bits of code:</p>
  
  <pre><code>private final Map&lt;Long, Bitmap&gt; avatars = new HashMap&lt;Long, Bitmap&gt;();
  
  // this is called *on the UI thread* by the background thread
  @Override
  public void onAvatarLoaded(long contactId, Bitmap avatar) {
      avatars.put(requestCode, avatar);
      notifyDataSetChanged();
  }
  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
      // snip...
      final Bitmap avatar = avatars.get(contact.id);
      if (avatar != null) {
          tag.avatar.setImageBitmap(avatar);
          tag.avatar.setVisibility(View.VISIBLE);
          tag.defaultAvatar.setVisibility(View.GONE);
      } else {
          tag.avatar.setVisibility(View.GONE);
          tag.defaultAvatar.setVisibility(View.VISIBLE);
          if (!avatars.containsKey(contact.id)) {
              avatars.put(contact.id, null);
              // schedule the picture to be loaded
              avatarLoader.addContact(contact.id, contact.id);
          }
      }
  }
  </code></pre>
  
  <p>AFAICT, if you assume that <code>notifyDataSetChanged()</code> causes the on-screen items to be re-created, my code is correct. However, it seems that is not true, or maybe I'm missing something. How can I make this work smoothly?</p>