iv.setImageDrawable(resource);
2、其他方法解释:
.asBitmap()和.asGif()
如果调用了.asBitmap()方法,则.load()中的参数指向的可以是一个静态图片也可以是GIF图片,如果是一张GIF图片,则加载之后只会展示GIF图片的第一帧
如果调用的.asGif()方法,则.load()方法中的参数指向的必须是一个GIF图片,如果是一张静态图片,则图片加载完成之后展示的只是图片占位符(如果没有设置图片占位符,则什么也不展示)
这两个方法中只能调用一个,调用了其中一个方法之后,代码提示就不会提示另一个了。代码:
Glide.with(MainActivity.this) // 在MainActivity中调用Glide的API
.load(IMAGE_STATIC_URL) // 加载网络中的静态图片
.asBitmap() // 将图片固定成静态图片
.placeholder(R.mipmap.ic_launcher) // 图片占位符
.into(iv); // 图片加载完成后直接放到ImageView对象iv中进行展示
.override()
这个方法可以设置图片加载之后展示的宽度值和高度值,前提是目标ImageView的宽度和高度都设置为wrap_content。代码:
Glide.with(MainActivity.this) // 在MainActivity中调用Glide的API
.load(IMAGE_STATIC_URL) // 加载网络中的静态图片
.override(666, 666) // 设置加载之后的图片显示的宽度和高度
.placeholder(R.mipmap.ic_launcher) // 图片占位符
.into(iv); // 图片加载完成后直接放到ImageView对象iv中进行展示
.thumbnail()
设置这个方法之后,可以先加载这张图片的sizeMultiplier倍的缩略图到目标ImageView中,然后再慢慢加载完整的图片。sizeMultiplier值的范围是0~1。代码:
Glide.with(MainActivity.this) // 在MainActivity中调用Glide的API
.load(IMAGE_STATIC_URL) // 加载网络中的静态图片
.thumbnail(0.1f) // 先加载一定比例的缩略图
.placeholder(R.mipmap.ic_launcher) // 图片占位符
.into(iv); // 图片加载完成后直接放到ImageView对象iv中进行展示
.animate()
加载图片时展示的动画,可以是Animator类型的属性动画,也可以是int类型的动画资源。这个动画只在第一次加载的时候会展示,以后都会从缓存中获取图片,因此也就不会展示动画了。代码:
Glide.with(MainActivity.this) // 在MainActivity中调用Glide的API
.load(IMAGE_STATIC_URL) // 加载网络中的静态图片
.animate(android.R.anim.slide_in_left) // 图片加载完成后的动画效果(从左侧滑入)
.into(iv); // 图片加载完成后直接放到ImageView对象iv中进行展示
.centerCrop()和.fitCenter()
如果调用了.centerCrop()方法,则显示图片的时候短的一边填充容器,长的一边跟随缩放
如果调用了.fitCenter()方法,则显示图片的时候长的一边填充容器,短的一边跟随缩放
这两个方法可以都调用,如果都调用,则最终显示的效果是后调用的方法展示的效果。代码:
Glide.with(MainActivity.this) // 在MainActivity中调用Glide的API
.load(IMAGE_STATIC_URL) // 加载网络中的静态图片
.fitCenter() // 长的一边填充容器
.centerCrop() // 短的一边填充容器
.into(iv); // 图片加载完成后直接放到ImageView对象iv中进行展示
.bitmapTransform()
.bitmapTransform()方法中传入的参数是一组Transformation类型的对象,即转换器,可以是任意多个。要想使用Glide为我们提供的转换器,我们需要先在build.gradle文件中导入Glide的Transformations的依赖:
compile 'jp.wasabeef:glide-transformations:1.0.6'
这个依赖中为我们提供了很多的转换器,如下:
圆形:CropCircleTransformation
方形:CropSquareTransformation
圆角:RoundedCornersTransformation
颜色覆盖:ColorFilterTransformation
置灰:GrayscaleTransformation
毛玻璃:BlurTransformation
使用转换器的时候直接new就可以了,但是需要传入一个BitmapPool的对象,我们可以直接传入一个new的LruBitmapPool。例如,我们想得到一个圆形图片的转换器,就可以编写如下代码:
LruBitmapPool pool = new LruBitmapPool((int) (Runtime.getRuntime().maxMemory()) / 8);
Glide.with(MainActivity.this) // 在MainActivity中调用Glide的API
.load(IMAGE_STATIC_URL) // 加载网络中的静态图片
.fitCenter() // 长的一边填充容器
.centerCrop() // 短的一边填充容器
.bitmapTransform(new CropCircleTransformation(pool)) // 转换器
.into(iv); // 图片加载完成后直接放到ImageView对象iv中进行展示
.resumeRequests()和.pauseRequests()
这两个方法是为了保证用户界面的滑动流畅而设计的。当在ListView中加载图片的时候,如果用户滑动ListView的时候继续加载图片,就很有可能造成滑动不流畅、卡顿的现象,这是由于Activity需要同时处理滑动事件以及Glide加载图片。Glide为我们提供了这两个方法,让我们可以在ListView等滑动控件滑动的过程中控制Glide停止加载或继续加载,可以有效的保证界面操作的流畅。
我们需要在ListView的OnScrollListener中写这部分的代码,如下(Adapter中的代码就不贴出来了):
// ListView滑动时触发的事件
lv.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
switch (scrollState) {
case AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
case AbsListView.OnScrollListener.SCROLL_STATE_FLING:
// 当ListView处于滑动状态时,停止加载图片,保证操作界面流畅
Glide.with(MainActivity.this).pauseRequests();
break;
case AbsListView.OnScrollListener.SCROLL_STATE_IDLE:
// 当ListView处于静止状态时,继续加载图片
Glide.with(MainActivity.this).resumeRequests();
break;
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
四、Glide的原理:
当Glide调用with()方法时,通过传入的Context对象获取一个RequestManager对象。RequestManager类中封装了一个RequestTracker,RequestTracker中有一个List<Request>集合,用来统一管理Request请求。
当RequestManager对象调用load()方法时,将参数中的值(String或URL或byte[])封装成一种ModelType类型的数据存储到GenericRequestBuilder对象中,并返回一个DrawableRequestBuilder类型的对象(DrawableRequestBuilder是GenericRequestBuilder的子类)。
当DrawableRequestBuilder对象调用into()方法时,会调用其父类GenericRequestBuilder的obtainRequest()方法,返回一个GenericRequest对象(这个对象是Request接口的一个实现类)。
GenericRequest对象经过一系列的准备工作之后,调用Engine对象的load()方法开始加载图片。load()方法的加载流程如下:
* Check the memory cache and provide the cached resource if present
* Check the current set of actively used resources and return the active resource if present
* Check the current set of in progress loads and add the cb to the in progress load if present
* Start a new load
正如上面的源码注释中介绍的一样,Glide首先去缓存中寻找图片(这个缓存就是一个图片池BitmapPool),如果缓存中有这张图片,则从缓存资源中取出图片进行加载;如果缓存中没有,则从“actively used resources”中找图片,源码中的“actively used resources”指的是一个弱引用组成的Map集合,即如果缓存中没有,就去弱引用中找这张图片,如果弱引用中有这张图片则从弱引用中取出来进行加载;如果弱引用中也没有,则从正在进行的load(Request)中查找有没有哪个Request正在加载这张图片,如果有的话就等待这个Request加载完成之后直接拿过来加载;如果还是没有的话,就只能新开启一个Request从网络中获取了。
从上面的分析可以看到,Glide加载图片的方式和三级缓存机制很像,Glide中的缓存BitmapPool就像三级缓存中的强引用LruCache,Glide中也有一个弱引用的集合。唯一不同的是,Glide中对正在进行的请求也做了筛选,保证同一张图片只建立一个Request进行加载即可。
这里顺便科普一下强引用和弱引用之间的工作流程:强引用是一片固定的空间,使用队列的形式存储数据,新来的图片存到队尾,这样可以保证队尾的永远都是最新、最后使用的图片,对头都是最老、最早使用的图片。当强引用中的空间存满的时候,会把对头的图片“踢”出来放到弱引用中。我们之所以要使用弱引用,是因为弱引用可以在内存满了的时候随时GC,因此通常都会用弱引用作为第二级缓存。
以上就是对Glide的工作流程的总结,有不对之处还望大家不吝赐教,谢谢!