android – 懒惰加载GridView与从互联网下载的图像

我一直在访问Stack Overflow多年,这是我第一次找不到任何可以解决我问题的帖子(至少我没有看到任何帖子).

我有一个带有自定义适配器的GridView,我已经覆盖它以返回由ImageView和TextView生成的自定义视图.

我在JSON使用AsyncTask从URL解析它们之后加载图像,将所有信息存储到doInBackground()方法中的ArrayList中,并在onPostExecute()方法中调用notifyDataSetChanged().一切安好.

现在我的问题是,当我启动活动时,它需要5-10秒的时间才能创建网格视图并将其自身呈现给实体中的用户.我想知道是否有办法首先显示文本信息的网格视图,然后每个图像将加载.这是否可能,因为它们都是用同一种方法创建的?

@Override
public View getView(int arg0, View arg1, ViewGroup arg2) {
    View v = null;
    if (arg1 == null) {
        LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(
                Context.LAYOUT_INFLATER_SERVICE);
        v = inflater.inflate(R.layout.custom_product_view, null);
    } else {
        v = arg1;
    }

    iv = (ImageView) v.findViewById(R.id.product_image);
    imageLoader.DisplayImage(products.get(arg0).getImage(), iv);

    TextView tv = (TextView) v.findViewById(R.id.product_price);
    tv.setText(products.get(arg0).getPrice());

    return v;
}

我也必须告诉你,你可以从DisplayImage()方法看到我已经实现了这个延迟加载:Lazy load of images in ListView.它工作正常,但问题是它再次加载整个视图.我想要做的是启动活动,首先加载标题,然后在完成下载后加载图像.使用此代码,它只是延迟加载网格视图的每个单元格包含的整个视图.我赚了几秒钟,因为我没有像以前一样下载所有图像,但仍然不是我正在寻找的.

非常感谢.

最佳答案
遵循这种方法.

首先,创建一个自定义WebImageView类,如下所示.

public class WebImageView extends ImageView {

    private Drawable placeholder, image;

    public WebImageView(Context context) {
        super(context);
    }
    public WebImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }
    public WebImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public void setPlaceholderImage(Drawable drawable) {
        placeholder = drawable;
        if (image == null) {
            setImageDrawable(placeholder);
        }
    }
    public void setPlaceholderImage(int resid) {
        placeholder = getResources().getDrawable(resid);
        if (image == null) {
            setImageDrawable(placeholder);
        }
    }

    public void setImageUrl(String url) {
        DownloadTask task = new DownloadTask();  
        task.execute(url);
    }

    private class DownloadTask extends AsyncTask<String, Void, Bitmap> {

        @Override
        protected Bitmap doInBackground(String... params) {
            String url = params[0];
            try {
                URLConnection conn = (new URL(url)).openConnection();
                InputStream is = conn.getInputStream();
                BufferedInputStream bis = new BufferedInputStream(is);

                ByteArrayBuffer baf = new ByteArrayBuffer(50); 
                int current = 0;
                while ((current=bis.read()) != -1) {
                    baf.append((byte)current);
                }

                byte[] imageData = baf.toByteArray();
                return BitmapFactory.decodeByteArray(imageData, 0, imageData.length);

            } catch (Exception e) {
                return null;
            }
        }

        @Override
        protected void onPostExecute(Bitmap result) {
            image = new BitmapDrawable(result);
            if (image != null) {
                setImageDrawable(image);
            }
        }
    }
}

接下来,在Activity中使用上面的自定义ImageView,如下所示:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    WebImageView imageView = (WebImageView) findViewById(R.id.webimage);
    imageView.setPlaceholderImage(R.drawable.ic_launcher);
    imageView.setImageUrl("http://www.google.co.in/images/srpr/logo3w.png");
}

简而言之,您正在为ImageView设置占位符图像,当下载完成时,该图像将被实际图像替换.因此GridView将立即呈现,不会有任何延迟.

实施细节:
因此,在您的自定义视图(使用图像文本)而不是使用简单的ImageView时,请使用如上所示的WebImageView.当您获得JSON响应时,使用标题设置TextView,使用图像URL设置WebImageView.
因此标题将立即显示,图像将懒惰加载.

转载注明原文:android – 懒惰加载GridView与从互联网下载的图像 - 代码日志