文章目录
- 引入
- Glide的优点:
- 缺点:
- 使用
- 常用方法:
- 从网络加载图片
- 从文件加载图片
- 加载`resource`资源
- 加载`URI`地址
- 设置占位图
- 出错时的图片
- 占位图
- 图片过渡的`Transitions`
- 自定义过渡动画
- 图片大小调整
- 缩放图片
- 播放`gif`
- `asGif()`
- 把`Gif`当作`Bitmap`播放
- 显示本地视频缩略图
引入
Glide
是Google
员工的开源项目,Google
官方App
中已经使用,在2015年的Google I/O
上被推荐。
Glide的优点:
- 使用简单
- 可配置度高,自适应程度高
- 支持多种数据源,网络、本地、资源、
Assets
等 - 支持
Gif
图片。 - 支持
WebP
。 - 加载速度快、流畅度高。
Glide
的with()
方法不光接受Context
,还接受Activity
和Fragment
,这样图片加载会和Activity/Fragment
的生命周期保持一致,比如Pause
状态在暂停加载,在Resume
的时候又自动重新加载。- 支持设置图片加载优先级。
- 支持缩略图,可以在同一时间加载多张图片到同一个
ImageView
中,例如可以首先加载只有ImageView
十分之一大小的缩略图,然后等再加载完整大小的图片后会再显示到该ImageView
上。 - 内存占用低,
Glide
默认的Bitmap
格式是RGB_565
,比ARGB_8888
格式的内存开销要小一半,所以图片质量会稍微差一些,当然这些配置都是可以修改的。 Glide
缓存的图片大小是根据ImageView
尺寸来缓存的的。这种方式优点是加载显示非常快。且可以设置缓存图片的尺寸- 默认使用
HttpUrlConnection
下载图片,可以配置为OkHttp
或者Volley
下载,也可以自定义下载方式。 - 默认使用两个线程池来分别执行读取缓存和下载任务,且可以自定义。
- 默认使用手机内置存储进行磁盘缓存,可以配置为外部存储,可以配置缓存大小,图片池大小。
- 在加载同样配置的图片时,
Glide
内存占用更少,因为Glide
是针对每个ImageView
适配图片大小后再存储到磁盘的,这样加载进内存的是压缩过的图片,内存占用自然就比较少。这种做法有助于减少OutOfMemoryError
的出现。 - 高效处理
Bitmap
,使用Bitmap Pool
来对Bitmap
进行复用,主动调用recycle
回收需要回收的Bitmap
,减小系统回收压力
缺点:
- 体积相对来说比较大,目前最新版的大小在
500k
左右 - 当我们从远程
URL
地址下载图片时,Picasso
相比Glide
要快很多。可能的原因是Picasso
下载完图片后直接将整个图片加载进内存,而Glide
还需要针对每个ImageView
的大小来适配压缩下载到的图片,这个过程需要耗费一定的时间。(当然我们可以使用thumbnail()
来减少压缩的时间)
使用
加载图片,需要至少传入三个参数:
with(Context context)
:Context
是很多android api
所必要的参数,glide
也一样。可以传递Activity/Fragment
,而且
它会和Activity/Fragment
的生命周期进行绑定。load(String imageUrl)
:图片的URL
地址。into(ImageView targetImageView)
:需要将加载的图片显示到的对应的ImageView
。
@Override public void onCreate(Bundle savedInstanceState) {
...
ImageView imageView = (ImageView) findViewById(R.id.my_image_view);
GlideApp.with(this).load("xxxxxx").into(imageView);
}
常用方法:
从网络加载图片
GlideApp.with(context).load(internetUrl).into(targetImageView);
从文件加载图片
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"file.jpg");
GlideApp.with(context).load(file).into(imageViewFile);
加载resource
资源
int resourceId = R.mipmap.ic_launcher;
GlideApp.with(context).load(resourceId).into(imageViewResource);
加载URI
地址
GlideApp.with(context).load(uri).into(imageViewUri);
设置占位图
GlideApp
.with(context)
.load(UsageExampleListViewAdapter.eatFoodyImages[0])
.placeholder(R.mipmap.placeholder) // 可用drawable
.into(imageViewPlaceholder);
出错时的图片
GlideApp
.with(context)
.load("xxxxx")
.placeholder(R.mipmap.ic_launcher)
.error(R.mipmap.wrong) // 出错时放置的图片
.into(imageViewError);
占位图
上面的error()
展位图是当资源无法获取时使用的,例如图片地址无效,但是还有另外一种情况是你传递了null
值。比如在一个显示用户资料列表中,由于并不是
每个人都有头像图片,所有这时可能会传递null
值。如果想要指定一个在传递null
值时显示的错误图片可以使用.fallback()
.
String nullString = null; // could be set to null dynamically
GlideApp
.with(context)
.load(nullString)
.fallback(R.drawable.wrong2)
.into(imageView);
图片过渡的Transitions
无论你是否使用占位图,在UI
过程中改变ImageView
的图片都是一个很大的动作。有一个简单的方法可以使这种改变变的更平滑,更容易让人接受,那就是使用
crossfade
动画。
GlideApp
.with(context)
.load(UsageExampleListViewAdapter.eatFoodyImages[0])
.placeholder(R.mipmap.ic_launcher) // can also be a drawable
.error(R.mipmap.wrong) // will be displayed if the image cannot be loaded
.transition(DrawableTransitionOptions.withCrossFade())// withCrossFade(int duration)方法可以传入时间,默认时间是300毫秒
.into(imageViewCombined);
自定义过渡动画
上面提供了crossfade
动画,但是有些时候我们需要自定义更多的样式。
Glide
也是支持xml
中自定义的动画文件的。
GlideApp
.with(context)
.load(eatFoodyImages[0])
.transition(GenericTransitionOptions.with(R.anim.zoom_in))
.into(imageView1);
图片大小调整
大多数情况下,实际放置的大小和获取的大小无法完全适配。
Glide
优化了在内存上的占用。Glide
在缓存和内存里自动限制图片的大小去适配ImageView
的尺寸。Picasso
也有同样的能力,但需要调用fit()
方法。用Glide
时,如果图片不需要自动适配ImageView
,调用override(horizontalSize, verticalSize)
,它会在将图片显示在ImageView
之前调整图片的大小。
这个设置也有利于没有明确目标,但在已知尺寸的视图上。例如,如果app
想要预先缓存在splash
屏幕上,还没法测量出摆放的控件具体宽高。但是如果你已经知道图片应当为多大,使用override
可以提供一个指定的大小的图片。
GlideApp
.with(context)
.load(UsageExampleListViewAdapter.eatFoodyImages[0])
.override(600, 200) // 将图像大小调整为这些尺寸(以像素为单位)。调整大小不考虑纵横比
.into(imageViewResize);
缩放图片
对于任何图像的任何处理,调整图像的大小可能会扭曲长宽比,丑化图片的显示。
Glide
提供了变换去处理图片显示:
CenterCrop()
会缩放图片让图片充满整个ImageView
的边框,然后裁掉超出的部分。ImageVIew
会被完全填充满,但是图片可能不能完全显示出。
fitCenter()
会缩放图片让两边都相等或小于ImageView
的所需求的边框。图片会被完整显示,可能不能完全填充整个ImageView
。
GlideApp
.with(context)
.load(UsageExampleListViewAdapter.eatFoodyImages[0])
.override(600, 200)
.centerCrop() // 这种裁剪技术缩放图像,使其填充请求的边界,然后裁剪多余的边界。
.into(imageViewResizeCenterCrop);
播放gif
String gifUrl = "https://s2.loli.net/2023/12/05/lM4cKaQUPmeurT8.gif";
GlideApp
.with(context)
.load(gifUrl)
.into(imageViewGif);
这里注意:如果提供的源不是
Gif
,可能是一个普通的图片。即使是一个完好的图片(非Gif
),Glide
也会加载失败。.error()
回调方法会被调用,并加载错误占位图,那么可以进行强迫生成gif。↓
asGif()
这样引入了一个额外的方法.asGif()
强迫生成一个Gif
。
GlideApp
.with(context)
.asGif()
.load(gifUrl)
.error(R.drawable.wrong)
.into(imageViewGif);
把Gif
当作Bitmap
播放
如果需要显示一组网络URL
,可能包括普通的图片或者Gif
。如果你只是想要显示Gif
的第一帧(图片),当URl
指向的的确是Gif
,你可以调用asBitmap()
将其作为常规图片显示。
GlideApp
.with(context)
.asBitmap()
.load(gifUrl)
.into(imageViewGif);
显示本地视频缩略图
String filePath = "/storage/emulated/0/Pictures/targetVideo.mp4";
GlideApp
.with(context)
.asBitmap()
.load(Uri.fromFile(new File(filePath)))
.into(imageViewGifAsBitmap);