在getView(适配器)上启动AsyncTask的ListView上的图像延迟加载

时间:2013-10-31 23:41:08

标签: android listview android-asynctask lazy-loading

我有一个ListView,其中的项目包含一些文本和一个ImageView。我想使用和AsyncTask来加载ImageView(延迟加载)。 我知道有一些库可以做到这一点。问题是无法使用URL获取图像,例如

imageLoader.displayImage(imageUri, imageView);

因为我需要在HTTP GET(身份验证令牌)中添加一些标头。因此,在适配器的getView()内部,我必须启动AsyncTask,将图像作为Bitmap下载并在ImageView上显示。

有代码示例吗?我试图将ImageView传递给AsyncTask构造函数中的AsyncTask,下载Bitmap并将其分配给onPostExecute上的ImageView,如下所示:

public class LoadImageTask extends AsyncTask<String, Void, Bitmap>{

private ImageView mImage;
private Context mContext;
private String imageId;
private Throwable mThrown = null;

public LoadImageTask(ImageView ivImage, Context context) {
    mImage = ivImage;
    mContext = context;
}

@Override
protected Bitmap doInBackground(String... params) {
    imageId = params[0];

      // Build request and request token
      ....
          //Process the response
            try {

                HttpEntity entity = mHttpResponse.getEntity();
                InputStream inputStream = entity.getContent();
                BufferedInputStream bis = new BufferedInputStream(inputStream);
                Bitmap bm = BitmapFactory.decodeStream(bis);
                bis.close();
                inputStream.close();
                return bm;
            } catch (IOException e) {
                mThrown = e;
                RestClient.consumeContent(mHttpResponse);
                return null;
            }

        }
        RestClient.consumeContent(mHttpResponse);
        return null;
}

@Override
protected void onPostExecute(Bitmap bm) {
    mImage.setImageBitmap(bm);
}

}

public View getView(int position, View convertView, ViewGroup parent) {
    LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View rowView = inflater.inflate(R.layout.news_item, null);
    TextView tvNewsTitle = (TextView) rowView.findViewById(R.id.tvNewsTitle);
    TextView tvUpdateDate = (TextView) rowView.findViewById(R.id.tvUpdateDate);
    ImageView ivImage = (ImageView) rowView.findViewById(R.id.ivNewsThumbnail);   

    News news = mNewsList.get(position);
    tvNewsTitle.setText(news.getTitle());
    tvUpdateDate.setText(news.getLastUpdate());
    new LoadImageTask(ivImage, mContext).execute(news.getImageThumbnail());
    return rowView;
}

但看起来它总是只更新ListView的第一个元素。

是否有任何示例代码?

2 个答案:

答案 0 :(得分:1)

请参阅git lazylist代码......

使用代码做你要求的......

OnClickInList OR在片段中用位图封装视图你需要...

  imgLoadr.DisplayImage(mMap.get("pic"), imgview);

上面对分支代码的调用依赖于(memCache Y / N中的位图,本地文件中的位图Y / N,通过URL在Web上使用位图)。

你不必担心上面的分支的实现.Lib为你处理它。

DisplayImage(){}...
    if(bitmap!=null){
            imageView.setImageBitmap(bitmap);
        }
        else
        {   
            queuePhoto(url, imageView);
            imageView.setImageResource(stub_id);

在runnable中设置HTTP HEADERS ...

 public Bitmap getBitmap(String url)
    {

        File f=fileCache.getFile(url);
        //from SD cache
        Bitmap b = decodeFile(f);
        if(b!=null)
            return b;

        //from web
        try {
            Bitmap bitmap=null;
            URL imageUrl = new URL(url);
            HttpURLConnection conn = (HttpURLConnection)imageUrl.openConnection();
            conn.setConnectTimeout(30000);
            conn.setReadTimeout(30000);
            conn.setInstanceFollowRedirects(true);
            InputStream is=conn.getInputStream();
            OutputStream os = new FileOutputStream(f);
            Utils.CopyStream(is, os);
            os.close();
            bitmap = decodeFile(f);
            return bitmap;
        } catch (Exception ex){

获取项目lazylist

在你身上

答案 1 :(得分:0)

droidQuery库具有延迟加载图像的速记和缩写方法。像你建议的那样,速记方法不允许添加标题:

$.with(myImageView).image(the_url);
然而,这是一个简写:

$.ajax(new AjaxOptions().url(the_url)
                        .type("GET")
                        .dataType("image")
                        .header("username", username)
                        .header("password", password)
                        .success(new Function() {
                            @Override
                            public void invoke($ d, Object... args) {
                                $.with(myImageView).image((Bitmap) args[0]);
                            }
                        }));