Android ListView updating of Image Thumbnails using AsyncTask Causes View recycling

后端 未结 3 1648
孤独总比滥情好
孤独总比滥情好 2020-12-13 16:37

I have been trying to get thumbnails to work with an AsyncTask for image files in a ListView. I have been having the common problem of Row Recycling, and thus on scrolling t

3条回答
  •  南笙
    南笙 (楼主)
    2020-12-13 16:57

    From this blog post:

    What you want to do is running all per-row IO or any heavy CPU-bound routine asynchronously in a separate thread. The trick here is to do that and still comply with ListView‘s recycling behaviour. For instance, if you run an AsyncTask to load a profile picture in the adapter’s getView(), the view you’re loading the image for might be recycled for another position before the AsyncTask finishes. So, you need a mechanism to know if the view hasn’t been recycled once you’re done with the async operation.

    One simple way to achieve this is to attach some piece of information to the view that identifies which row is associated with it. Then you can check if the target row for the view is still the same when the async operation finishes. There are many ways of achieving this. Here is just a simplistic sketch of one way you could do it:

    public View getView(int position, View convertView,
            ViewGroup parent) {
        ViewHolder holder;
    
        ...
    
        holder.position = position;
    
        new ThumbnailTask(position, holder)
                .executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, null);
    
        return convertView;
    }
    
    private static class ThumbnailTask extends AsyncTask {
        private int mPosition;
        private ViewHolder mHolder;
    
        public ThumbnailTask(int position, ViewHolder holder) {
            mPosition = position;
            mHolder = holder;
        }
    
        @Override
        protected Cursor doInBackground(Void... arg0) {
            // Download bitmap here
        }
    
        @Override
        protected void onPostExecute(Bitmap bitmap) {
            if (mHolder.position == mPosition) {
                mHolder.thumbnail.setImageBitmap(bitmap);
            }
        }
    }
    
    private static class ViewHolder {
        public ImageView thumbnail;
        public int position;
    }
    

提交回复
热议问题