Android URL图片在listview中随机播放

时间:2016-05-30 11:50:51

标签: android json listview

我刚刚注意到,当我从一个网址中将我的图片加载到一个列表视图中时,有时候它们会在它们正确定位之前循环显示。我该如何防止这种情况发生?

这是我自定义适配器的异步任务

private class AsyncDownloadTask extends AsyncTask<Object, String, Bitmap>{

        private View view;
        private Bitmap bitmap = null;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            if(bitmap!=null&&view!=null){
                ImageView newsIcon = (ImageView)view.getTag(R.id.newsIcon);
                newsIcon.setImageBitmap(bitmap);
            }
        }

        @Override
        protected Bitmap doInBackground(Object... params) {
            view = (View)params[0];
            String uri = (String)params[1];
            try{
                InputStream inputStream = new URL(uri).openStream();
                bitmap = BitmapFactory.decodeStream(inputStream);
            }catch (Exception e){
                e.printStackTrace();
            }
            return bitmap;
        }
    }

这是我的getview

@Override
    public View getView(int position, View convertView, ViewGroup parent) {

        View row = convertView;
        if(position==0){

            NewsObj currNews = news.get(position);
            DataHandler dh;
            if(convertView==null){
                LayoutInflater inflater = (LayoutInflater)this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                row = inflater.inflate(R.layout.firstnews,parent,false);
                dh = new DataHandler();
                dh.newsTitle = (TextView)row.findViewById(R.id.newsTitle);
                dh.newsDate = (TextView)row.findViewById(R.id.newsDate);
                dh.newsIcon = (ImageView)row.findViewById(R.id.newsIcon);
                row.setTag(dh);
            }else{
                dh = (DataHandler)row.getTag();
            }
            NewsObj no = (NewsObj)this.getItem(position);
            row.setTag(R.id.newsIcon,row.findViewById(R.id.newsIcon));
            new AsyncDownloadTask().execute(row,no.getImgurl());
            dh.newsTitle.setText(no.getTitle());
            dh.newsDate.setText(no.getDate());

        }else{

            NewsObj currNews = news.get(position);
            DataHandler dh;
            if(convertView==null){
                LayoutInflater inflater = (LayoutInflater)this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                row = inflater.inflate(R.layout.newslist,parent,false);
                dh = new DataHandler();
                dh.newsTitle = (TextView)row.findViewById(R.id.newsTitle);
                dh.newsDate = (TextView)row.findViewById(R.id.newsDate);
                dh.newsIcon = (ImageView)row.findViewById(R.id.newsIcon);
                row.setTag(dh);
            }else{
                dh = (DataHandler)row.getTag();
            }
            NewsObj no = (NewsObj)this.getItem(position);
            row.setTag(R.id.newsIcon, row.findViewById(R.id.newsIcon));
            new AsyncDownloadTask().execute(row,no.getImgurl());
            dh.newsTitle.setText(no.getTitle());
            dh.newsDate.setText(no.getDate());

        }
        return row;
    }

2 个答案:

答案 0 :(得分:3)

你做错了导致这个问题,你将你的观点绑定到任务。理论上它会导致显示图像的不一致,例如,如果您的图像视图被引用到两个任务中,那么任务完成最后一个将设置位图。如何解决此问题只需将任务引用设置为图像视图的标记,然后在创建新任务之前首先从图像视图中获取旧任务,如果它不为空且未完成取消并创建新任务。

这里是位重构代码试试这个。

@Override
    public View getView(int position, View convertView, ViewGroup parent) {

        View row = convertView;
        DataHandler dh;
        if(position==0){

            NewsObj currNews = news.get(position);
            if(convertView==null){
                LayoutInflater inflater = (LayoutInflater)this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                row = inflater.inflate(R.layout.firstnews,parent,false);
                dh = new DataHandler();
                dh.newsTitle = (TextView)row.findViewById(R.id.newsTitle);
                dh.newsDate = (TextView)row.findViewById(R.id.newsDate);
                dh.newsIcon = (ImageView)row.findViewById(R.id.newsIcon);
                row.setTag(dh);
            }else{
                dh = (DataHandler)row.getTag();
            }
            NewsObj no = (NewsObj)this.getItem(position);
            row.setTag(R.id.newsIcon,row.findViewById(R.id.newsIcon));
            dh.newsTitle.setText(no.getTitle());
            dh.newsDate.setText(no.getDate());

        }else{

            NewsObj currNews = news.get(position);
            if(convertView==null){
                LayoutInflater inflater = (LayoutInflater)this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                row = inflater.inflate(R.layout.newslist,parent,false);
                dh = new DataHandler();
                dh.newsTitle = (TextView)row.findViewById(R.id.newsTitle);
                dh.newsDate = (TextView)row.findViewById(R.id.newsDate);
                dh.newsIcon = (ImageView)row.findViewById(R.id.newsIcon);
                row.setTag(dh);
            }else{
                dh = (DataHandler)row.getTag();
            }
            NewsObj no = (NewsObj)this.getItem(position);
            row.setTag(R.id.newsIcon, row.findViewById(R.id.newsIcon));
            dh.newsTitle.setText(no.getTitle());
            dh.newsDate.setText(no.getDate());

        }
      AsyncTask task = (AsyncTask)dh.newsIcon.getTag();
      if(task!=null && task.getStatus()!=FINISHED){
      task.cancel();
      }
       task = new AsyncDownloadTask();
       dh.newsIcon.setTag(task);
       task.execute(row,no.getImgurl());

        return row;
    }

答案 1 :(得分:0)

不确定它是否有效但也许您可以将图像uri字符串也放在DataHandler中。并在postExecute中检查它,以便只有当它与最后一个匹配时才应用它:

    @Override
    protected void onPostExecute(Bitmap bitmap) {
        if(bitmap!=null&&view!=null && ((DataHandler)view.getTag()).uri.equals(this.uri){
            ImageView newsIcon = (ImageView)view.getTag(R.id.newsIcon);
            newsIcon.setImageBitmap(bitmap);
        }
    }

然后在As doInBackground

中设置AsyncTask中的私有String uri