最近项目中有个需求,加载网络图片时,图片未显示出来时,显示占位符,占位符为一个圆弧不停旋转效果,图片加载完成后,占位符消失。

loading.gif
众所周知,Glide加载图片时是支持占位符功能的,占位符是当请求正在执行时被展示的 Drawable,当请求成功完成时,占位符会被请求到的资源替换。
Glide.with(this).load(url).placeholder(placeholder).into(imageView)
或者
Glide.with(this).load(url).placeholder(placeholderDrawable).into(imageView)
那就开工做吧,先实现静态占位符,然后再实现loading效果,其中用到的图片资源如下:

icon_place_holder.png
1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|
![]() loading_01.png
|
![]() loading_02.png
|
![]() loading_03.png
|
![]() loading_04.png
|
![]() loading_05.png
|
![]() loading_06.png
|
![]() loading_07.png
|
![]() loading_08.png
|
![]() loading_09.png
|
![]() loading_10.png
|
![]() loading_11.png
|
![]() loading_12.png
|
![]() loading_13.png
|
![]() loading_14.png
|
![]() loading_15.png
|
![]() loading_16.png
|
![]() loading_17.png
|
![]() loading_18.png
|
![]() loading_19.png
|
![]() loading_20.png
|
![]() loading_21.png
|
![]() loading_22.png
|
![]() loading_23.png
|
![]() loading_24.png
|
![]() loading_25.png
|
实现静态占位符
在drawable
文件夹下定义place_holder.xml
,内容如下:
在加载图片时使用占位符资源:
Glide.with(this).load("http://image.huajiao.com/943063fe44aa1bcc4ece46ccbf358af8.jpg").placeholder(R.drawable.place_holder).into(imageView)

静态占位符.png
实现占位符loading效果
修改一下place_holder.xml
,在layer-list
节点下添加一个item
,在此item
中添加一个animation-list
,命名为place_holder_animation.xml
,内容如下:
然后在加载图片时使用该占位符资源:
Glide.with(this).load("http://image.huajiao.com/943063fe44aa1bcc4ece46ccbf358af8.jpg").placeholder(R.drawable.place_holder_animation).into(imageView)
运行一下,发现占位符并没有loading动画效果,圆弧没有旋转,也就是在xml里定义的帧序列没有做动画,我太难了😭😭😭。既然如此,就在代码里加载占位符资源,找到动画序列,开启该动画,然后在图片资源加载成功后停止该动画。添加一个ImageView的扩展方法,代码如下:
/**
* 加载图片,带loading动画效果的占位符
*/
fun ImageView.loadWithAnimation(
context: Context,
url: String,
listener: RequestListener? = null
) {
val placeHolderDrawable = ContextCompat.getDrawable(context, R.drawable.place_holder_animation)
var animationDrawable: Drawable? = null
if (placeHolderDrawable is LayerDrawable) {
animationDrawable = placeHolderDrawable.findDrawableByLayerId(R.id.layer_animation)
if (animationDrawable is AnimationDrawable) {
animationDrawable.start()
}
}
val callback = object : RequestListener {
override fun onLoadFailed(
e: GlideException?,
model: Any,
target: Target,
isFirstResource: Boolean
): Boolean {
listener?.onLoadFailed(e, model, target, isFirstResource)
return false
}
override fun onResourceReady(
resource: Drawable,
model: Any,
target: Target,
dataSource: DataSource?,
isFirstResource: Boolean
): Boolean {
listener?.onResourceReady(resource, model, target, dataSource, isFirstResource)
if (animationDrawable is AnimationDrawable) {
if (animationDrawable.isRunning) {
animationDrawable.stop()
}
}
return false
}
}
Glide.with(context).load(url).placeholder(placeHolderDrawable).listener(callback).into(this)
}
然后在加载图片时调用以下代码:
imageView.loadWithAnimation(this,"http://image.huajiao.com/943063fe44aa1bcc4ece46ccbf358af811.jpg")
运行一下,圆弧就动起来了,😃😃😃,这样就实现了Glide占位符loading效果了。
代码地址
https://github.com/kongpf8848/AndroidWorld