我正在使用ListView来显示与这些图像相关的一些图像和标题。我正在从互联网上获取图像。是否有一种方法可以延迟加载图像,以便在文本显示时,UI不会被阻止,图像在下载时显示?

图像总数不是固定的。


当前回答

你必须试试这个通用加载器。我在做了很多关于延迟加载的RnD之后使用了这个。

通用图像加载器

特征

多线程图像加载(异步或同步)ImageLoader配置的广泛定制(线程执行器、下载器、解码器、内存和磁盘缓存、显示图像选项等)每个显示图像调用都有许多自定义选项(存根图像、缓存开关、解码选项、位图处理和显示等)内存和/或磁盘上的图像缓存(设备的文件系统或SD卡)收听加载过程(包括下载进度)

Android 2.0+支持

其他回答

我可以推荐一种类似魅力的不同方式:Android Query。

您可以从这里下载JAR文件

AQuery androidAQuery = new AQuery(this);

例如:

androidAQuery.id(YOUR IMAGEVIEW).image(YOUR IMAGE TO LOAD, true, true, getDeviceWidth(), ANY DEFAULT IMAGE YOU WANT TO SHOW);

它非常快速和准确,使用它,您可以找到更多的功能,如加载时的动画、获取位图(如果需要)等。

你必须试试这个通用加载器。我在做了很多关于延迟加载的RnD之后使用了这个。

通用图像加载器

特征

多线程图像加载(异步或同步)ImageLoader配置的广泛定制(线程执行器、下载器、解码器、内存和磁盘缓存、显示图像选项等)每个显示图像调用都有许多自定义选项(存根图像、缓存开关、解码选项、位图处理和显示等)内存和/或磁盘上的图像缓存(设备的文件系统或SD卡)收听加载过程(包括下载进度)

Android 2.0+支持

毕加索

使用杰克·沃顿的毕加索图书馆。(ActionBarSherlock开发人员提供的完美图像加载库)

一个强大的Android图像下载和缓存库。

图像为Android应用程序添加了急需的上下文和视觉效果。Picasso允许在应用程序中轻松加载图像,通常只需一行代码!

Picasso.with(context).load("http://i.imgur.com/DvpvklR.png").into(imageView);

在Android上加载图像的许多常见陷阱都由毕加索自动处理:

在适配器中处理ImageView回收和下载取消。使用最少内存的复杂图像转换。自动内存和磁盘缓存。

毕加索杰克·沃顿图书馆

滑行

Glide是一个快速高效的Android开源媒体管理框架,它将媒体解码、内存和磁盘缓存以及资源池打包成一个简单易用的界面。

Glide支持获取、解码和显示视频剧照、图像和动画GIF。Glide包含一个灵活的API,允许开发人员插入几乎任何网络堆栈。默认情况下,Glide使用一个基于HttpUrlConnection的自定义堆栈,但也包括Google的Volley项目或Square的OkHttp库的实用程序库插件。

Glide.with(this).load("your-url-here").into(imageView);

Glide的主要关注点是尽可能平滑快速地滚动任何类型的图像列表,但Glide对于任何需要获取、调整大小和显示远程图像的情况都非常有效。

Glide图像加载库

Facebook上的壁画

Fresco是一个在Android应用程序中显示图像的强大系统。

Fresco负责图像加载和显示,因此您不必这样做。它将从网络、本地存储或本地资源加载图像,并在图像到达之前显示占位符。它有两级缓存;一个在存储器中,另一个在内部存储器中。

壁画Github

在Android4.x及更低版本中,Fresco将图像放在Android内存的一个特殊区域。这让您的应用程序运行得更快,并且更少发生可怕的OutOfMemoryError。

壁画文献

我只想再添加一个很好的示例,XML适配器。由于它被谷歌使用,我也在使用相同的逻辑来避免OutOfMemory错误。

基本上,这个ImageDownloader就是你的答案(因为它涵盖了你的大部分需求)。有些也可以在其中实现。

另一种方法是通过getView()方法中线程中的适配器:

Thread pics_thread = new Thread(new Runnable() {
    @Override
    public void run() {
        Bitmap bitmap = getPicture(url);
        if(bitmap != null) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    holder.imageview.setImageBitmap(bitmap);            
                    adapter.notifyDataSetChanged();
                }                       
            });             
        }       
    }                       
});

pics_thread.start();

当然,您应该始终缓存图像以避免额外的操作,您可以将图像放在HashMap数组中,检查图像是否存在于数组中,如果不存在,则继续执行线程或从HashMap数组加载图像。此外,请始终检查内存是否泄漏,位图和可绘制文件通常占用大量内存。优化代码取决于您。