2

我有一个GridView其中包含一个Adapter扩展ArrayAdapter<Album>(专辑是从 LastFM API 获得的专辑信息)。

Album信息带有图像的 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;
    }
}
4

1 回答 1

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();
        }
于 2012-11-27T08:58:56.960 回答