Sketch 支持播放 GIF、WEBP、HEIF 动图,每一种动图都有相应的 DrawableDecoder 提供支持,如下:
Type | Decoder | APi Limit | Additional Module |
---|---|---|---|
GIF | GifAnimatedDrawableDecoder | Android 9+ | _ |
GIF | GifMovieDrawableDecoder | Android 4.4+ | sketch-gif-movie |
GIF | GifDrawableDrawableDecoder | Android 4.1+ | sketch-gif-koral |
WEBP Animated | WebPAnimatedDrawableDecoder | Android 9+ | _ |
HEIF Animated | HeifAnimatedDrawableDecoder | Android 11+ | _ |
注意:
- GifMovieDrawableDecoder 和 GifDrawableDrawableDecoder 需要依赖额外的模块
- GIF 提供了三种 DrawableDecoder 可以根据 app 支持的最低版本选择合适的
sketch-gif-movie
模块使用 Android 自带的 Movie 类实现播放 GIF,不会额外增加包体积sketch-gif-koral
模块使用 koral--/android-gif-drawable 库的 GifDrawable 类实现播放 gif,库体积大概 250 KB
Sketch 默认并没有注册任何动图的 DrawableDecoder,需要你主动将 DrawableDecoder 注册到 Sketch 才能播放动图
通过在 Application 类实现 SketchFactory 接口并使用 components 函数将 DrawableDecoder 注册到 Sketch,这样所有的 ImageRequest 都可以使用,如下:
class MyApplication : Application(), SketchFactory {
override fun createSketch(): Sketch {
return Sketch.Builder(this).apply {
components {
addDrawableDecoder(
when {
VERSION.SDK_INT >= VERSION_CODES.P -> GifAnimatedDrawableDecoder.Factory()
VERSION.SDK_INT >= VERSION_CODES.KITKAT -> GifMovieDrawableDecoder.Factory()
else -> GifDrawableDrawableDecoder.Factory()
}
)
if (VERSION.SDK_INT >= VERSION_CODES.P) {
addDrawableDecoder(WebpAnimatedDrawableDecoder.Factory())
}
if (VERSION.SDK_INT >= VERSION_CODES.R) {
addDrawableDecoder(HeifAnimatedDrawableDecoder.Factory())
}
}
}.build()
}
}
或者在显示图片时只给当前 ImageRequest 注册,这样就只有当前 ImageRequest 可以使用,如下:
imageView.displayImage("https://www.example.com/image.gif") {
components {
addDrawableDecoder(
when {
VERSION.SDK_INT >= VERSION_CODES.P -> GifAnimatedDrawableDecoder.Factory()
VERSION.SDK_INT >= VERSION_CODES.KITKAT -> GifMovieDrawableDecoder.Factory()
else -> GifDrawableDrawableDecoder.Factory()
}
)
if (VERSION.SDK_INT >= VERSION_CODES.P) {
addDrawableDecoder(WebpAnimatedDrawableDecoder.Factory())
}
if (VERSION.SDK_INT >= VERSION_CODES.R) {
addDrawableDecoder(HeifAnimatedDrawableDecoder.Factory())
}
}
}
ImageRequest 和 ImageOptions 都提供了相关方法用于动图相关配置,如下:
imageView.displayImage("https://www.example.com/image.gif") {
// 禁用动图,会只解码动图的第一帧
disallowAnimatedImage()
// 配置动图播放 1 次就停止,默认无限循环播放
repeatCount(1)
// 监听动图开始和停止播放
onAnimationStart {
// ...
}
onAnimationEnd {
// ...
}
// 对动图的每一帧在绘制时进行修改
animatedTransformation { canvas ->
// ...
}
}
动图相关的 DrawableDecoder 统一返回 SketchAnimatableDrawable,SketchAnimatableDrawable 实现了 Animatable2Compat 接口
你可以通过 Animatable2Compat 接口的 start() 和 stop() 方法手动控制开始播放和停止播放
GenericViewDisplayTarget 在将 SketchAnimatableDrawable 显示到 ImageView 上之后会检查 ImageRequest.lifecycle 的状态,如果 lifecycle 的状态大于 start 就开始播放
GenericViewDisplayTarget 会监听 ImageRequest.lifecycle 的 start 和 stop 状态自动控制播放