ListView图像并使用convertView

时间:2014-09-24 16:08:10

标签: android android-listview android-lru-cache

我在ListView中加载图片并使用convertView添加新项目。我发现当我快速向下滚动时,几个屏幕上的图像会显示在当前的图像之前..在getView中我实例化AsyncTask。我该如何解决?是否可以使图像缓存工作,或者我是否必须找到与已启动的AsyncTasks通信的方法,并告诉他们停止加载未能显示的图像?

以下是相关代码:

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    if (convertView == null) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = inflater.inflate(R.layout.list_item_course, null);
    }
    CourseItem courseItem = courseItemList.get(position);

    // ImageView
    Bitmap bm = courseItem.getPhotoBitmap();

    ImageView iv = (ImageView) convertView.findViewById(R.id.imageView1);       
    iv.setAdjustViewBounds(true);
    iv.setMaxHeight(imageWidth);
    iv.setMaxWidth(imageWidth);     

    if (bm != null) {
        iv.setImageBitmap(bm);
    } else {
        CourseItemAndView container = new CourseItemAndView();
        container.courseItem = courseItem;
        container.view = convertView;

        ImageLoader loader = new ImageLoader();
        loader.execute(container);                  
    }   

...

return convertView;
}

private class CourseItemAndView {
    public CourseItem courseItem;
    public Bitmap bitmap;
    public View view;
}

private class ImageLoader extends AsyncTask<CourseItemAndView, Void, CourseItemAndView> {

    @Override
    protected CourseItemAndView doInBackground(CourseItemAndView... params) {

        CourseItemAndView container = params[0];
        CourseItem ci = container.courseItem;

        try {
            String imageUrl = ci.getSmallIcon();
            InputStream in = (InputStream) new URL(imageUrl).getContent();
            Bitmap bitmap = BitmapFactory.decodeStream(in);
            if (bitmap == null)
                System.out.println("HERE");
            ci.setPhotoBitmap(bitmap);
            in.close();
            container.bitmap = bitmap;
            return container;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(CourseItemAndView result) {
        if (result == null) {
            System.out.println("HERE");
        } else {
            ImageView iv = (ImageView) result.view.findViewById(R.id.imageView1);
            iv.setImageBitmap(result.bitmap);
        }
    }

}

1 个答案:

答案 0 :(得分:0)

为了让异步任务知道列表视图的项目位置,所以它可以在想要放置位图时相应地执行操作,在asynctask中添加position和listview参数。并使用asynctask实例标记imageview。

  ImageLoader loader = new ImageLoader(listView, position);
  container.view.setTag(loader);
  loader.execute(container);     

然后在onPostExecute中,当position位于listview的可见项之外时,不必放置位图。

  if( position < listView.getFirstVisiblePosition() 
     || position > listView.getLastVisiblePosition()
     )
      return;

然后检查任务是否属于图像视图:

if ( imageView.getTag() != this )
     return;

.... place bitmap ..