同一个 ImageView
切换图片显示时会闪现一下 placeHolder
,如果 placeHolder
为空则会闪现一下背景,原因有两个:
into
方法会取消上一次加载,最终会调用到[Target.onLoadCleared]
方法,如果是直接into(ImageView)
,则会把原来的图置空并设置placeHolder
, 如果是继承[CustomViewTarget]
,则会接着调用到[CustomViewTarget.onResourceLoading]
;[ImageViewTarget.onLoadStarted]
时会把原来的图置空并设置placeHolder
。
但是有的场景是不希望用 placeHolder
的。所以需要一种选择加载中是否使用 placeHolder
的能力,如果 placeHolder
不为空,则会使用 placeHolder
,为空则不使用,此时 ImageView
会显示上次加载的图,直到当前图加载完或加载失败。
abstract class SeamlessImageViewTarget<Z>(view: ImageView) : CustomViewTarget<ImageView, Z>(view), ViewAdapter {
private var animatable: Animatable? = null
override fun onStart() {
animatable?.start()
}
override fun onStop() {
animatable?.stop()
}
override fun getCurrentDrawable(): Drawable? = view.drawable
override fun setDrawable(drawable: Drawable?) {
view.setImageDrawable(drawable)
}
override fun onLoadFailed(errorDrawable: Drawable?) {
setResourceInternal(null)
setDrawable(errorDrawable)
}
override fun onResourceLoading(placeholder: Drawable?) {
super.onResourceLoading(placeholder)
// placeholder 为空则不设置,会显示上一张图
placeholder?.let { setDrawable(placeholder) }
}
override fun onResourceReady(resource: Z, transition: Transition<in Z>?) {
if (transition == null || !transition.transition(resource, this)) {
setResourceInternal(resource)
} else {
maybeUpdateAnimatable(resource)
}
}
override fun onResourceCleared(placeholder: Drawable?) {
animatable?.stop()
// placeholder 为空则不设置,会显示上一张图
placeholder?.let { setDrawable(placeholder) }
}
private fun setResourceInternal(resource: Z?) {
// Order matters here. Set the resource first to make sure that the Drawable has a valid and
// non-null Callback before starting it.
setResource(resource)
maybeUpdateAnimatable(resource)
}
private fun maybeUpdateAnimatable(resource: Z?) {
animatable = if (resource is Animatable) {
resource.apply { start() }
} else {
null
}
}
protected abstract fun setResource(resource: Z?)
}
class SeamlessBitmapImageViewTarget(view: ImageView) : SeamlessImageViewTarget<Bitmap>(view) {
override fun setResource(resource: Bitmap?) {
view.setImageBitmap(resource)
}
}
class SeamlessDrawableImageViewTarget(view: ImageView) : SeamlessImageViewTarget<Drawable>(view) {
override fun setResource(resource: Drawable?) {
view.setImageDrawable(resource)
}
}
复制代码