与其他图片加载库相同,Glide 除了可以加载网络图片之外,也可以加载本地图片。甚至还可以从各种各样奇葩的数据源中加载图片。
加载网络图片
很多情况下,我们使用图片加载库就是为了加载网络图片。网络操作是一个很复杂的东西。试想一下,如果没有图片加载库,我们就要手动去下载图片,缓存图片,最后再从文件里面读取 bitmap 并设置到 Imageview 里面。这还算好的,要是在 Listview 里面你会更头疼的。原因我就不说了,你懂的~~再加上各种各样的 Bitmap 操作,保准你再也不想撸代码了。而且 Bitmap 这东西还很占内存,伺候不好,很容易就会引发 OOM,app 吧唧就闪退了!!
图片加载库的优势就在于此。简简单单一句话,下载,缓存,加载统统搞定。简直就是美好一生的东西。而 Glide 就是这样使人美好一生的东西之一。
说了这么多,Glide 如何加载网络图片?很简单,就上次的三句话:
1 | ImageView targetImageView = (ImageView) findViewById(R.id.imageView); |
木有什么乱七八糟的东西,直接传入要加载图片的 url 就可以了。那么图片加载库有很多,为什么选择 Glide 呢?很简单,因为它流畅,不卡,尤其是在 Listview 中。嗯,就是酱~
加载本地图片
下表是.load()可以传入的参数及说明
参数 | 说明 |
---|---|
.load(String string) | string 可以为一个文件路径、uri 或者 url |
.load(Uri uri) | uri 类型 |
.load(File file) | 文件 |
.load(Integer resourceId) | 资源 Id,R.drawable.xxx 或者 R.mipmap.xxx |
.load(byte[] model) | byte[]类型 |
.load(T model) | 自定义类型 |
从上面可以看到 Glide 不仅可以加载网络图片,还可以加载本地图片。可接受的参数有文件路径,uri,文件,资源 id 等。基本上满足了大部分的需求。虽然加载本地图片不像网络图片那样复杂,但我还是建议使用 Glide 来加载本地图片。因为它是内存友好的,而且还会“偷偷地”帮我们做很多事情。比如内存缓存,Bitmap 复用,修正照片方向等。当然为了满足各种各样的需求,仅仅加载图片是不够的,你还需要对图片进行各种各样的变换,也就是 Transformation。后面我们会详细了解的。
加载自定义数据源
前面的表格中有一个是我们不熟悉的,就是.load(T model),即自定义的数据源类型。那么如何去实现呢?
实际上,加载自定义数据源主要是通过 ModelLoader 接口来实现的。由于没有在实际项目中用到过,这方面的经验比较少。想深入了解的,可以参考这篇文章。
不过从官方 Wiki 上来看,设计 ModelLoader 接口的初衷用来加载不同尺寸的图片的。众所周知,Android 设备屏幕分辨率千奇百怪,大到 2K,小到 320p。如果在低分辨率的手机上加载大图,不仅损耗用户流量,而且很容易造成 OOM;在高分辨的手机上,加载小图又会出现模糊的情况,用户体验极差。很多时候,为了省事,很多 app 都会选择一个中间分辨率,然后自适应大小。当然这样做无可厚非,但是有更好的办法,我们为什么不去尝试呢?
那么如何使用 Glide 来实现这一具体需求呢?首先你要实现自己的 ModelLoader,比较简单的方法是继承BaseGlideUrlLoader。
1 | public interface MyDataModel { |
接下来我们可以这样来加载图片:
1 | Glide.with(this) |
.using(new MyUrlLoader(this)):使用我们自己的 ModeLoader;
.load(new MyDataModel()):加载我们自定义的数据源
这里需要解释下 getUrl 的三个参数:
model:你加载的数据源
width:你加载的图片的宽度(px)
height:你加载的图片的高度(px)
这样,我们在高分率的设备上加载大图的 url1,在低分辨率的设备上加载小图 url2。从而实现了根据不同手机上的像素值大小加载不同尺寸的图片的需求。
当然如果你不想每次都是用.using(new MyUrlLoader()),就需要实现一个自定义的ModelLoaderFactory并在 GlideModule 中注册。
1 | public class MyGlideModule implements GlideModule { |
同时也要在 AndroidManifest.xml 声明
1 | <meta-data |
如果你有多个自定义的 GlideModule 类,那么也要在 AndroidManifest.xml 中声明多个 GlideModule。
对于上面的加载不同尺寸的图片,Google 的 2014 年 I/O 大会 App 中有一篇文章专门用来介绍这个的,地址在这里。大概原理是这样子的:
在服务端有下面的几个可以加载的 url:
URL | 图片大小 |
---|---|
myserver.com/images/__w-200-400-600-800-1000__/session1.jpg | 原始尺寸 |
myserver.com/images/w200/session1.jpg | 200px |
myserver.com/images/w400/session1.jpg | 400px |
myserver.com/images/w600/session1.jpg | 600px |
myserver.com/images/w800/session1.jpg | 800px |
myserver.com/images/w1000/session1.jpg | 1000px |
那么客户端如何根据不同的手机分辨率去加载不同的 url 呢?
Google 是这样做的,下面是核心代码:
1 | //定义正则表达式 |
大概的步骤如下: 1.根据服务端可加载的图片 url 定义正则表达式 2.根据正则匹配,获取到可以加载的图片尺寸数组 3.根据要加载的 Imageview 的大小,选择合适的尺寸的 url 4.拼接 url 并返回
上面的例子中有 200,400,600,800,1000 是可以加载的,如果你要加载的 Imageview 的大小为 600px,当遍历数组到 600 时,就会直接跳出循环,返回 600px 大小图片的 url,Glide 就会加载 600px 的图片。
最后送上一个小 demo:https://github.com/Alluretears/GldieDemo