本文的内容大部分都是参考了下面这个连接中Glide
分类的文章:android
为了区分,咱们这篇只介绍一些基本用法,掌握这些基本就能够在项目中使用Glide
了,而关于如何自定义Target/Glide Module
等高级的用法,以后再进行讨论。github
在使用前,首先须要在build.gradle
中引入:缓存
dependencies {
//....
compile 'com.github.bumptech.glide:glide:3.7.0'
//...
}
复制代码
下面是Glide
加载一张网络静态图片最基本的用法:bash
Glide
.with(this) //传入关联的Context,若是是Activity/Fragment,那么它会根据组件当前的状态来控制请求。
.load("http://i.imgur.com/DvpvklR.png") //须要加载的图片,大多数状况下就是网络图片的连接。
.into(getImageView()); //用来展示图片的ImageView.
复制代码
load
的其它用法在第二章的例子当中,当咱们调用完.with(Context context)
以后,会返回一个RequestManager
对象,以前咱们就是调用它的load(String string)
方法,除此以外,还提供了下面的这些load
方法,load
方法最终会返回一个DrawableTypeRequest<xxxx>
,而xxx
就是咱们传入的参数的类型: 服务器
load(byte[] model)
,从byte[]
中读取load(File file)
,从File
中读取load(Integer resourceId)
,从resourceId
中读取load(String string)
,从String
当中读取,这个通常对应于网络图片的连接,这个图片有多是普通的图片,也多是一个Gif
,当咱们须要展现一个Gif
图片时,只须要像加载普通图片同样就能够了,在加载完以后,这个Gif
会被自动播放。load(T model)
,从任意类型T
的中读取,这个后面讲到自定义Model
时再介绍load(Uri uri)
,从Uri
类型中读取,这个Uri
必须可以被UriLoader
识别。loadFromMediaStore(Uri uri)
,从媒体设备的Uri
中读取,这个方法用来展现一个本地媒体视频的缩略图,也就是视频的第一帧,须要注意,这个连接只能是本地的,网络上视频连接地址是无效的。下面是各个方法加载的例子:网络
//从byte[]中加载.
public void loadByteArray(View view) {
Bitmap sourceBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.book_local);
ByteArrayOutputStream bArrayOS = new ByteArrayOutputStream();
sourceBitmap.compress(Bitmap.CompressFormat.PNG, 100, bArrayOS);
sourceBitmap.recycle();
byte[] byteArray = bArrayOS.toByteArray();
try {
bArrayOS.close();
} catch (Exception e) {
e.printStackTrace();
}
Glide.with(this)
.load(byteArray)
.into(mImageView);
}
//从File中加载.
public void loadFile(View view) {
String storePath = "mnt/sdcard/book_local.jpg";
File file = new File(storePath);
Glide.with(this)
.load(file)
.into(mImageView);
}
//从resourceId中加载.
public void loadResourceId(View view) {
Glide.with(this)
.load(R.drawable.book_local)
.into(mImageView);
}
//从普通url中加载.
public void loadNormalUrl(View view) {
Glide.with(this)
.load("http://i.imgur.com/DvpvklR.png")
.into(mImageView);
}
//从gif加载.
public void loadGif(View view) {
Glide.with(this)
.load("http://s1.dwstatic.com/group1/M00/66/4D/d52ff9b0727dfd0133a52de627e39d2a.gif")
.diskCacheStrategy(DiskCacheStrategy.SOURCE) //要加上这句,不然有可能会出现加载很慢,或者加载不出来的状况.
.into(mImageView);
}
//从本地媒体视频中加载.
public void loadMedia(View view) {
String storePath = "mnt/sdcard/media.mp4";
File file = new File(storePath);
Glide.with(this)
.load(Uri.fromFile(file))
.into(mImageView);
}
复制代码
有时候因为网络缘由,致使请求耗时,此时就须要在获得图片资源以前,采用一个占位图片,这样就不会显得界面太空,placeHolder
就是作这个事的,当咱们调用了into
方法以后,若是须要从网络上获取图片,那么它会先展现placeHolder
设置的图片,placeHolder
除了支持传入resourceId
,还支持直接传入一个Drawable
对象。框架
@Override
public DrawableRequestBuilder<ModelType> placeholder(int resourceId) {
super.placeholder(resourceId);
return this;
}
@Override
public DrawableRequestBuilder<ModelType> placeholder(Drawable drawable) {
super.placeholder(drawable);
return this;
}
复制代码
使用placeHolder
的例子:ide
public void loadHolder(View view) {
Glide.with(this)
.load("http://i.imgur.com/DvpvklR.png")
.placeholder(R.drawable.book_placeholder)
.into(mImageView);
}
复制代码
有时候,当咱们请求网络图片失败时,咱们但愿给用户一些提示,这时候给它设置一些回调,并在回调当中进行处理。可是通常状况下,咱们显示一个表示错误的本地图片就能够了,为了和前面加载时的占位图片区分,它提供了另外一个error()
方法,和placeHolder
相似,咱们能够给它传入一个resourceId
或者Drawable
对象。gradle
public void loadHolderError(View view) {
Glide.with(this)
.load("http://i.imgur.com/DvpvklR.png")
.asGif() //为了模拟加载失败的状况.
.placeholder(R.drawable.book_placeholder)
.error(R.drawable.book_error)
.into(mImageView);
}
复制代码
上面为了模拟失败的状况,咱们传入了一个png
的连接,可是指定为加载asGif()
资源。 咱们发现它会先展现placeHolder
的资源,再展现error
的资源。
不管是placeHolder
仍是error
,都会涉及到切换ImageView
的图片,这时咱们能够经过设置一个动画来让这个切换的过程显得不那么突兀,默认状况下动画是开启的,crossFade
有下面这三个重载方法:
crossFade()
:采用默认动画和默认时长。crossFade(int duration)
:采用默认动画,自定义时长。crossFade(int animationId, int duration)
:采用自定义动画,并自定义时长。public void loadCustomCrossFade(View view) {
Glide.with(this)
.load("http://i.imgur.com/DvpvklR.png")
.placeholder(R.drawable.book_placeholder)
.crossFade(5000) //改变的时长.
.into(mImageView);
}
复制代码
固然咱们也能够经过dontAnimate
,来关闭动画,这样在切换的时候就不会出现动画。
public void loadNoCrossFade(View view) {
Glide.with(this)
.load("http://i.imgur.com/DvpvklR.png")
.placeholder(R.drawable.book_placeholder)
.dontAnimate()
.into(mImageView);
}
复制代码
和Picasso
相比,Glide
提供了一种更加高效的处理方式,它会把内存和缓存中的图片限制到所展现的ImageView
的返回内,Picasso
也能够实现这一功能,可是须要调用fit()
方法。在使用Glide
时,若是咱们不但愿它自动地去匹配ImageView
的宽高,那么能够调用override(width, height)
,这样图片资源在被展现以前就会裁剪为指定的大小。
这个方法还有另外一种场景,就是当咱们确切的知道须要加载多大的图片,可是此时ImageView
的宽高并无获得。
由于有时候采用override
直接裁剪图片有可能致使只裁剪到了没必要要的信息,所以Glide
还提供了两个相似于ImageView
中的scaleType
属性:
centerCrop
:使原始的图片的宽高按同等比例放大到override
所指定的大小,并裁剪到多余的部分,这时最终的图片资源的大小为(width, height)
fitCenter
:使得原始图片的宽高放大到小于等于override
所指定的宽高,所以,咱们最终获得图片的大小有可能不为(width, height)
,也就是说不会撑满整个ImageView
。 下面是相关的代码:public void loadOverride(View view) {
Glide.with(this)
.load(R.drawable.shader_pic)
.override(20, 20)
.into(mImageView);
}
public void loadOverrideCenterCrop(View view) {
Glide.with(this)
.load(R.drawable.shader_pic)
.override(20, 20)
.centerCrop()
.into(mImageView);
}
public void loadOverrideFitCenter(View view) {
Glide.with(this)
.load(R.drawable.shader_pic)
.override(20, 20)
.fitCenter()
.into(mImageView);
}
复制代码
ImageView
的scaleType
的关系因为ImageView
的展现还须要受android:scaleType
的影响,这里状况有不少,因此上面裁剪出来,并非说在ImageView
里面展现就是20 * 20
,具体会出现的状况不少,这个以后再专门分析。
Gif
图片在第二节中,咱们简单的介绍了如何用Glide
展现Gif
图片的展现,下面咱们深刻地讨论一下其它两点。
asGif()
有时候,咱们获取的Gif
图片连接是服务器配置的,所以咱们没法知道这个连接究竟是不是一个Gif
图片。这时咱们能够配置一个asGif()
选项,这样Glide
就会知道咱们是须要加载一个Gif
图片,当这个连接不是Gif
时,加载就会失败,若是咱们定义了.error(xxx)
,就会展现这个失败的图片。 例如,下面这段代码就会失败:
public void loadHolderError(View view) {
Glide.with(this)
.load("http://i.imgur.com/DvpvklR.png") //传入的是一个静态图片的连接.
.asGif() //为了模拟加载失败的状况.
.placeholder(R.drawable.book_placeholder)
.error(R.drawable.book_error)
.into(mImageView);
}
复制代码
asBitmap()
如今讨论另一种状况,在列表当中,虽然咱们得到的是Gif
连接,可是咱们但愿这时候不让它播放,这时候就能够指定asBitmap()
,那么就只会展现Gif
图片的第一帧。
若是咱们使用了.diskCacheStrategy(DiskCacheStrategy.SOURCE)
,那么Gif
资源的加载将会更快。
对于任何一个网络图片加载框架来讲,缓存无疑是最关键的部分,Glide
使用了内存和磁盘缓存来避免没必要要的网络请求,同时它也提供了一系列地接口让使用者自定义缓存策略。
默认状况下,Glide
会将图片资源缓存到内存当中。而若是使用了skipMemoryCache(true)
,Glide
不会将这张图片缓存到内存当中。 有一点须要注意:若是以前对某个指向url
的图片使用了内存缓存,后面又用skipMemoryCache(true)
声明想让同一个url
不缓存到内存中,那么是不会生效的。
当某个图片变化很快时,咱们有可能不须要将它缓存到磁盘当中,咱们能够采用diskCacheStrategy(int mode)
来定义缓存的策略,Glide
默认状况下既会缓存原始的图片,也会缓存解析后的图片,举个例子,假如服务器上的图片是1000 * 1000
,而ImageView
的大小只有500 * 500
,默认状况下Glide
会缓存这两个版本的图片,咱们能够设定的磁盘缓存类型有下面四种:
DiskCacheStrategy.NONE
:不缓存DiskCacheStrategy.SOURCE
:只缓存原始大小的图片,也就是1000 * 1000
。DiskCacheStrategy.RESULT
:只缓存解析以后的图片,也就是上面500 * 500
的图片,也就是说假如咱们有两个不一样大小的ImageView
,用他们加载同一个url
的图片,那么最终磁盘当中会有两份不一样大小的图片资源。DiskCacheStrategy.ALL
:缓存全部版本的图片。如今咱们介绍一下采用了DiskCacheStrategy.RESULT
后的缓存文件名的命名策略,具体能够参考下面这篇文章:
https://github.com/bumptech/glide/wiki/Caching-and-Cache-Invalidation
缓存文件的命名会依赖于四个部分:
DataFecher
的getId()
方法的返回值,通常状况下就是Data Model
的toString
方法。对于传入String
类型的网络连接而言,就是url
,而若是是File
,那么就是File
的path
。override(width, height)
,那就是指定的数值,默认状况下是Target
的getSize()
方法,也就是ImageView
的宽高。encoders
和decoders
的toString
方法。url
没有变,可是服务器上这个url
对应的图片资源更新了,咱们就能够经过.signature(xxx)
来刷新缓存。上面咱们讨论了两种缓存策略的定义,这两种策略是相互独立的,默认状况下内存的缓存为打开,而磁盘的缓存策略为DiskCacheStrategy.ALL
。
有时候,在同一个界面上咱们会展现多个图片,而为了用户体验,那么某个图片咱们但愿先加载出来,这时候就能够采用.priority(int priority)
来定义请求的优先级,固然,这些优先级只是给Glide
做为参考,由于还涉及到图片的大小,服务器的响应事件和网络环境等因素,最后图片展现的顺序并不必定是根据优先级来的,可选的优先级包括:
Priority.LOW
Priority.NORMAL
Priority.HIGH
Priority.IMMEDIATE
前面,咱们介绍了placeHolder
,它能够指定一个本地资源,用来在网络资源加载完成以前进行展现,而thumbnails
则能够认为是一个动态的placeHolder
,与placeHolder
不一样,咱们能够给它指定一个网络图片连接。若是这个缩略图请求在load
请求以前返回那么,那么会先展现这个图片,等到load
请求返回以后,这个图片就会消失。假如缩略图的请求在load
请求以后返回,那么请求结果会被丢弃掉。 Glide
提供了两种指定缩略图的方式:
Simple Thumbnails
public void loadScaleThumbnail(View view) {
Glide.with(this)
.load("http://i.imgur.com/DvpvklR.png")
.diskCacheStrategy(DiskCacheStrategy.NONE)
.thumbnail(0.1f)
.into(mImageView);
}
复制代码
Complete Different Request
thumbnails
还支持传入一个Glide Request
做为参数,这个请求和本来的请求是相互独立的,咱们能够给它指定一个彻底不一样的url
、缓存策略、大小等等。
public void loadRequestThumbnail(View view) {
DrawableRequestBuilder<String> thumbnailRequest = Glide
.with(this)
.load("http://i.imgur.com/DvpvklR.png");
Glide.with(this)
.load("http://s1.dwstatic.com/group1/M00/66/4D/d52ff9b0727dfd0133a52de627e39d2a.gif")
.diskCacheStrategy(DiskCacheStrategy.NONE)
.thumbnail(thumbnailRequest)
.into(mImageView);
}
复制代码