【问题标题】:Lazy load of images on ListView with AsyncTask launched on the getView (adapter)在 getView(适配器)上启动 AsyncTask 在 ListView 上延迟加载图像
【发布时间】:2013-10-31 23:41:07
【问题描述】:

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

imageLoader.displayImage(imageUri, imageView);

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

有代码示例吗?我尝试在 AsyncTask 的构造函数中将 ImageView 传递给 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 的第一个元素。

有示例代码吗?

【问题讨论】:

  • 我在去年写了一些完全一样的东西——我会看看能不能找到它。基本上,您需要确保确实完成了 Web 服务调用。
  • 你检查过其他图片是否达到 null 吗?

标签: android listview android-asynctask lazy-loading


【解决方案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);

在可运行文件中设置您的 HTTP 标头...

 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

在你里面

【讨论】:

    【解决方案2】:

    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]);
                                }
                            }));
    

    【讨论】:

      猜你喜欢
      • 2016-01-26
      • 2015-10-12
      • 1970-01-01
      • 1970-01-01
      • 2011-02-24
      • 1970-01-01
      • 2013-11-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多