2

我有一個GridView其中包含Adapter其中ArrayAdapter<Album>(其中專輯是從LastFM API獲取的相冊信息)。ImageView通過GridView獲取回收

Album info帶有一個圖像的URL。我異步下載這些圖像,並將它們與專輯名稱一起放入Adapter

但是,當我向下滾動GridView時,行會被回收。當我再次膨脹它們時,圖像會互換,我不知道發生了什麼。

我試過將圖像存儲在HashMap<String, Bitmap>無濟於事。

這裏是我的Adapter

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<Album> { 

    private final ImageDownloader d; 
    int playcount; 

    @SuppressLint("UseSparseArrays") 
    private final HashMap<Integer, View> map = new HashMap<Integer, View>(); 

    public AlbumAdapter(final Context ctx, final Artist artist) { 
     super(ctx, 0); 
     d = new ImageDownloader(); 
     new AsyncTask<Void, Void, Void>() { 
      CopyOnWriteArrayList<Album> albums = new CopyOnWriteArrayList<Album>(); 

      @Override 
      protected Void doInBackground(final Void... params) { 
       final Collection<Album> albumCollection = Artist 
         .getTopAlbums(artist.getName()); 
       for (final Album album : albumCollection) { 
        if (playcount < 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<Void, Void, Void>() { 
        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 >= 90) { 
      tv2.setTextColor(0xff99ff33); 
     } else if (percentage >= 75) { 
      tv2.setTextColor(0xffffff66); 
     } else if (percentage >= 50) { 
      tv2.setTextColor(0xffff9900); 
     } else if (percentage >= 25) { 
      tv2.setTextColor(0xffcc6600); 
     } else { 
      tv2.setTextColor(0xffcc0000); 
     } 
     return convertView; 
    } 
} 

回答

1
  1. 你應該使用模式ViewHolder的代碼:

    public class NewHolder { 
        public ImageView ivIcon; 
        public TextView tvTitle; 
        public int position; 
    } 
    
  2. @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
        NewHolder holder = null; 
    
        UBRNew item = data.get(position); 
    
        if (convertView == null) { 
         holder = new NewHolder(); 
         convertView = inflater.inflate(R.layout.item_new, null); 
         holder.tvTitle = (TextView) convertView.findViewById(R.id.tvTitle); 
         holder.ivIcon = (ImageView) convertView.findViewById(R.id.ivIcon); 
         convertView.setTag(holder); 
        } else { 
         holder = (NewHolder) convertView.getTag(); 
        } 
    
    holder.position = position; 
    
    holder.tvTitle.setText(Tools.replaceCharactersInEllipsis(item.getTitle())); 
    holder.ivIcon.setImageBitmap(((item.getIcon() == null) ? defaultIconForNew : item.getIcon())); 
    
    if ((!isFling) && (!item.isDownloadedIcon())) { 
        new LazyLoadImage(context, 
             this, 
             item, 
             holder, 
             position, 
             64, 
             64).execute(); 
    } 
    
        return convertView; 
    } 
    

3.

公共類LazyLoadImage擴展的AsyncTask {

private final String TAG = "LazyLoadThumbnail"; 

private NewHolder holder = null; 
private UBRNew ubrNew = null; 
private int position = 0; 
private AdapterUbrNews adapter = null; 
private int widthIcon = 0; 
private int heightIcon = 0; 
private DBNews db = null; 
private Context context = null; 

public LazyLoadImage(Context context, 
        AdapterUbrNews adapter, 
        UBRNew ubrNew, 
        NewHolder holder, 
        int position, 
        int widthIcon, 
        int heightIcon) { 
    this.adapter = adapter; 
    this.holder = holder; 
    this.position = position; 
    this.ubrNew = ubrNew; 
    this.widthIcon = widthIcon; 
    this.heightIcon = heightIcon; 

    this.ubrNew.setDownloadedIcon(true); 

    db = DBNews.getInstance(context); 

    this.context = context; 
} 

@Override 
protected Bitmap doInBackground(Void... voids) { 
    Bitmap result = null; 

    try { 
     Bitmap temp = download(ubrNew.getUrlIcon()); 

     if (temp != null) { 
      result = Bitmap.createScaledBitmap(temp, widthIcon, heightIcon, true); 
     } 
    } catch (MalformedURLException e) { 
     e.printStackTrace(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 

    return result; 
} 

@Override 
protected void onPostExecute(Bitmap bitmap) { 
    if (bitmap != null) { 
     ubrNew.setIcon(bitmap); 

     if (position == holder.position) { 
      holder.ivIcon.setImageBitmap(bitmap); 
     } else { 
      adapter.notifyDataSetChanged(); 
     } 
    } else { 
     ubrNew.setDownloadedIcon(false); 
    } 
} 

private Bitmap download(String urlString) throws MalformedURLException, IOException { 
    if ((urlString == null) || (urlString.equals(""))) { 
     return null; 
    } 

    DefaultHttpClient client = new DefaultHttpClient(); 
    HttpGet getRequest = new HttpGet(urlString); 

    try { 
     HttpResponse response = client.execute(getRequest); 
     final int statusCode = response.getStatusLine().getStatusCode(); 
     if (statusCode != HttpStatus.SC_OK) { 
      return null; 
     } 

     final HttpEntity entity = response.getEntity(); 
     if (entity != null) { 
      InputStream inputStream = null; 
      try { 
       inputStream = entity.getContent(); 
       return BitmapFactory.decodeStream(inputStream); 
      } finally { 
       if (inputStream != null) { 
        inputStream.close(); 
       } 
      } 
     } 
    } catch (Exception e) {} 

    return null; 
} 

}

在LazyLoadImage所有功能摘錄:

if (position == holder.position) { 
      holder.ivIcon.setImageBitmap(bitmap); 
     } else { 
      adapter.notifyDataSetChanged(); 
     } 
+0

我會測試它,當我下班回家,現在我種忙。我沒有忘記給你接受的答案,只是我現在無法測試;-) – razielsarafan

+0

好的。如果你有問題,你會寫電子郵件給我(在我的個人資料中) – Vladimir