android - 使用 AsyncTask for Android ListView 更新图像缩略图不正确

标签 android image performance listview android-asynctask

我从服务器得到了一个很大的响应,包含数据和图像 url。我需要在 ListView 中显示它们。图片应该像缩略图。为了使其正确,我自定义了我的适配器并使用异步任务获取图像。这是我的适配器和异步任务代码:

   public class TalkofTownAdapter extends BaseAdapter{

    private LayoutInflater inflater = null;
    private Context context = null;
    ImageView thumb_image = null;
    private ProgressDialog progressbar = null;

    ArrayList<String> items;
    ArrayList<String> thumb_url;
     public TalkofTownAdapter(Context c, ArrayList<String> list, ArrayList<String> thumb) 
     {
         this.context = c;
         this.items = list;
         this.thumb_url = thumb;
         progressbar = new ProgressDialog(c);
         Log.d("Testing", "talk of town adapter constructor   "+items.size());
         inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

     }
    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return items.size();
    }
    @Override
    public Object getItem(int position) {
        // TODO Auto-generated method stub
        return position;
    }
    @Override
    public long getItemId(int position) {
        // TODO Auto-generated method stub
        return position;
    }

    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.talkoftown, null);
            Log.d("Testing", "before creating holder object");
            holder = new ViewHolder();
            holder.headlineView = (TextView) convertView.findViewById(R.id.list_title);
            holder.duration = (TextView)convertView.findViewById(R.id.duration);
            holder.imageView = (ImageView) convertView.findViewById(R.id.list_image_playlist);
            Log.d("Testing", "image view created ::::::::   ");
            convertView.setTag(holder);
        } else {
            holder = (ViewHolder) convertView.getTag();
        }
        Log.d("Testing", "text:::   "+items.get(position));
        holder.headlineView.setText(items.get(position));
        Log.d("Testing", "settting the text   ");
        holder.duration.setText("22/09/1987");

        if (holder.imageView != null) {
            Log.d("Testing", "getting the image  "+thumb_url.get(position));
            new ImageDownloaderTask(holder.imageView).execute(thumb_url.get(position));
        }

        return convertView;
    }

    static class ViewHolder {
        TextView headlineView;
        TextView duration;
        ImageView imageView;
    }


    public static Bitmap getBitmapFromURL(String src) {
        try {
            URL url = new URL(src);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setDoInput(true);
            connection.connect();
            InputStream input = connection.getInputStream();
            Bitmap myBitmap = BitmapFactory.decodeStream(input);
            Log.d("Testing", "image loaded  "+myBitmap);
//          myBitmap = Bitmap.createBitmap(100, 50, Config.ARGB_8888);
            myBitmap = Bitmap.createScaledBitmap(myBitmap,(int)(myBitmap.getWidth()), (int)(myBitmap.getHeight()), true);
            return myBitmap;
        } catch (IOException e) {
            Log.d("Testing", "exception is getting the image "+e.toString());
            e.printStackTrace();
            return null;
        }
    }
    public void startProgress()
    {
        progressbar.setMessage("Please wait");
        progressbar.show();
    }

    public void stopProgress()
    {
        progressbar.dismiss();
    }

    class ImageDownloaderTask extends AsyncTask<String, Void, Bitmap> {
        private final WeakReference<ImageView> imageViewReference;

        public ImageDownloaderTask(ImageView imageView) {
            imageViewReference = new WeakReference<ImageView>(imageView);
        }

        @Override
        // Actual download method, run in the task thread
        protected Bitmap doInBackground(String... params) {
            // params comes from the execute() call: params[0] is the url.
            return getBitmapFromURL(params[0]);
        }

        @Override
        // Once the image is downloaded, associates it to the imageView
        protected void onPostExecute(Bitmap bitmap) {
            if (isCancelled()) {
                bitmap = null;
            }

            if (imageViewReference != null) {
                ImageView imageView = imageViewReference.get();
                if (imageView != null) {
                    if (bitmap != null) {
                        imageView.setImageBitmap(bitmap);
                    } else {
                        imageView.setImageDrawable(imageView.getContext().getResources()
                                .getDrawable(R.drawable.rihanna));
                    }
                }

            }
        }
    }

现在缩略图显示为默认图像,然后随着下载图像的变化而变化。但是,如果我向下滚动 ListView ,图像会不断变化,并且会重复出现在上面行中的那些已经向上滚动的图像。所以我的意思是在这里说,图像是按照相应行的正确顺序出现的。我知道这里也有很多教程和 QA。但是我尝试了很多解决方案,但都没有正常工作。

谁能帮我解决这个问题?

最佳答案

问题出在你的 if 条件上。只需删除 if 条件 if (holder.imageView != null) { 问题是每次 getView 都会检查您的 View 是否为 null,并根据它执行并膨胀图像。

像这样改变你的if条件

    if(thumb_url.get(position) !=null)
    {
      Log.d("Testing", "getting the image  "+thumb_url.get(position));
        new ImageDownloaderTask(holder.imageView).execute(thumb_url.get(position));
    }

关于android - 使用 AsyncTask for Android ListView 更新图像缩略图不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20391422/

相关文章:

android - react native 模态显示超慢 iOS 但不是 Android

java - 如何使用 Appium 更改日期选择器中的日期

java - 简单 Intent - jUnit 测试失败

java - 为什么我的图像不能显示在我的 Java Applet 中?

javascript - 根据在文本字段中输入的值更改 Img Src

python - 在 python 中使用大型字典? (性能和崩溃)

android - 如何处理自定义 android View /小部件的可见性更改

java - 如何使用 jorda 时间将时区转换为 UTC 时区

Java 图像编辑器 UI 组件

python - 加速(简单)文本处理