ImageView被GridView回收

时间:2012-11-27 08:41:04

标签: android android-imageview android-gridview android-adapter

我有GridView,其中包含Adapter,其中ArrayAdapter<Album>扩展Album(其中相册是从LastFM API获取的相册信息)。

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 个答案:

答案 0 :(得分: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. 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();
            }