前面我们在《图片框架Picasso的简单使用》这篇博客说过了Picasso的简单使用,在这篇博客中我们就说一下另外一个很好的图片加载框架Glide。
Glide库的作者是bumptech。这个库被广泛的运用在google的开源项目中,包括2014年google I/O大会上发布的官方app。
bumptech发布地址:https://github.com/bumptech/glide/wiki
jar包下载地址:https://github.com/bumptech/glide/releases
在线文档:http://bumptech.github.io/glide/javadocs/latest/index.html
推荐一篇对Glide的介绍文章:https://inthecheesefactory.com/blog/get-to-know-glide-recommended-by-google/en
Glide和Picasso的一个简单比较:
① Picasso和Glide都在jcenter上。在项目中添加依赖非常简单:
// Picasso
dependencies {
compile 'com.squareup.picasso:picasso:2.5.1'
}
// Glide
dependencies {
compile 'com.github.bumptech.glide:glide:3.5.2'
compile 'com.android.support:support-v4:22.0.0'
}
需要注意的是Glide需要 Android Support Library v4 包,不过这不是什么大问题,因为现在 Android Support Library v4 基本是每一个新 Android 项目的标配了。
② Glide和Picasso使用起来非常相似(包括设置大小、转换等操作):
// Picasso
Picasso.with(context)
.load("http://inthecheesefactory.com/uploads/source/glidepicasso/cover.jpg")
.into(ivImg);
// Glide
Glide.with(context)
.load("http://inthecheesefactory.com/uploads/source/glidepicasso/cover.jpg")
.into(ivImg);
虽然两者看起来非常相似,但是 Glide 的代码无疑设计得更好,因为 Glide 的 with() 方法不光接受 Context,还接受 Activity 和 Fragment。此外,with()方法还能自动地从你放入的各种东西里面提取出 Context,供它自己使用。同 时将Activity/Fragment作为with()参数的好处是:
图片加载会和Activity/Fragment的生命周期保持一致,比如Paused状态在暂停加载,在Resumed的时候又自动重新加载。所以建议传参的时候传递Activity 和Fragment给Glide,而不是Context。
③ Glide默认Bitmap格式是RGB_565,而Picasso默认Bitmap的格式是RGB_888。在Glide中如果需要RGB_888格式的图片,Glide也能轻易实现转换(在下面部分有实现过程)。
④ Glide可以加载GIF图片,而Picasso则不能。
⑤ Picasso和Glide在磁盘缓存策略上有很大的不同。Glide缓存的图片和ImageView的尺寸相同,而Picasso缓存的图片和原始图片的尺寸相同。Picasso只缓存一个全尺寸的。Glide则不同,它会为每种大小的ImageView缓存 一次。尽管一张图片已经缓存了一次,但是假如你要在另外一个地方再次以不同尺寸显示,需要重新下载,调整成新尺寸的大小,然后将这个尺寸的也缓存起来。
具体说来就是:假如在第一个页面有一个200x200的ImageView,在第二个页面有一个100x100的ImageView,这两个ImageView本来是要显示同一张图片,却需要下载两次。
Glide这种方式优点是加载显示非常快,而Picasso的方式则因为需要在显示之前重新调整大小而导致一些延迟。当然Glide因为缓存了多张图片,所以要占用更多的磁盘空间。不过Glide可以指定缓存行为。
Glide的使用:
导包(开发工具:Android studio):
dependencies {
...
compile 'com.github.bumptech.glide:glide:3.7.0'
compile 'com.android.support:appcompat-v7:23.4.0'// v7包中已经包含了v4包
}
① 一行代码完成加载图片
Glide.with(MainActivity.this).load(imageUrl).into(imageView);
② 不仅可以加载网络图片,也可以加载本地(资源)文件图片
// 从文件加载
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"Test.jpg");
Glide.with(context).load(file).into(imageViewFile);
// 从资源id
int resourceId = R.mipmap.ic_launcher;
Glide.with(context).load(resourceId).into(imageViewResource);
// 从uri
Glide.with(context).load(uri).into(imageViewUri);
③ 指定正在加载和加载失败显示的图片
Glide.with(MainActivity.this)
.load(imageUrl)
.placeholder(R.mipmap.loading)// 正在加载时显示的图片
.error(R.mipmap.error) // 加载失败时显示的图片
.into(imageView);
④ 改变图片大小
Glide.with(MainActivity.this)
.load(imageUrl)
.override(300, 300) // 设置图片显示的宽和高
.placeholder(R.mipmap.loading)
.error(R.mipmap.error)
.into(imageView);
⑤ 图片的缩放,centerCrop()和fitCenter()
Glide.with(MainActivity.this)
.load(imageUrl)
.fitCenter()
//.centerCrop()
.into(imageView);
centerCrop()方法缩放图像让它填充 ImageView 并且裁剪额外的部分。ImageView 会完全填充,但图像可能不会完整显示。(裁剪图片,让图片填充控件)
fitCenter()方法让图片在ImageView中完整显示,但可能图片不会填满整个 ImageView控件。(图片完整显示,但是不保证完全填充控件)
⑥ 让用户先看到一个低解析度的图(缩略图)
Glide.with(MainActivity.this)
.load(ImageUrl.images[34])
.centerCrop()
.thumbnail( 0.1f )// 表示为原图的十分之一
.into(imageView);
⑦ 使用加载动画
Glide.with(MainActivity.this)
.load(ImageUrl.images[34])
.centerCrop()
//.crossFade() // 淡入淡出效果,使用默认时间,300毫秒
//.crossFade(1000) // 淡入淡出效果,指定时间,单位:毫秒
//.crossFade(animationId,1000) // 指定动画资源id和动画播放时间
//.animate(android.R.anim.slide_in_left) // 动画资源id(自定义的动画资源id)
//.animate(自定义的Animation对象)
.dontAnimate() // 不使用动画
.into(imageView);
使用动画时注意,如果是从缓存中获取到的图片资源,因为加载非常快,所以默认是不会再使用加载动画了,即使指定了加载动画。可以通过设置监听的方式指定从缓存中加载图片时也使用加载动画(使用监听在下面会有代码示例)。
⑧ 加载GIF图片
Glide.with(MainActivity.this)
//.load(imageUrl)
.load("http://img4.duitang.com/uploads/blog/201405/19/20140519115336_mQNyR.thumb.224_0.gif")
// .asBitmap() // 将GIF图片转换为Bitmap显示,只显示GIF的一帧
// asGif()方法:对GIF图片进行检查,如果是GIF图片正常显示;
// 如果不是GIF图片,加载失败(如果设置了错误图片就显示错误图片,没有设置错误图片就什么都不显示)。
.asGif()
.error(R.mipmap.error)
.centerCrop()
.into(imageView);
淡入淡出动画(为了看出效果,设置的时间比较长) 加载GIF图片 将GIF图片作为Bitmap显示,只显示一帧
⑨ 请求优先级设置
Glide.with(MainActivity.this)
.load(ImageUrl.images[34])
.centerCrop()
.priority(Priority.HIGH)
.into(imageView);
// 优先级取值,下面是优先级由高到低顺序
public enum Priority {
IMMEDIATE,
HIGH,
NORMAL,
LOW, priority,
}
⑩ 当ListView、GridView快速滑动时不加载图片
当列表在快速滑动的时候,调用Glide.with(context).pauseRequests()取消请求,
滑动停止时,调用Glide.with(context).resumeRequests()恢复请求。
// 设置滑动监听
listView.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
if (scrollState == SCROLL_STATE_IDLE || scrollState == SCROLL_STATE_TOUCH_SCROLL) {
// 停止滑动或者手指滑动listview时加载图片
Glide.with(MainActivity.this).resumeRequests();
}else if(scrollState == SCROLL_STATE_FLING){
// 手指离开根据惯性快速滑动时不加载图片
Glide.with(MainActivity.this).pauseRequests();
}
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
}
});
接下一篇博客《图片框架Glide的使用(二)》。