Translations: 简体中文
Sketch provides the sketch-animated-*
series of modules to support animated graphics. The
supported platforms and differences are as follows:
Module | DecoderProvider | Decoder | Android | iOS | Desktop | Web |
---|---|---|---|---|---|---|
sketch-animated-gif | GifDecoderProvider | android api 28+: ImageDecoderGifDecoder android api 27-: MovieGifDecoder non android: SkiaGifDecoder |
✅ | ✅ | ✅ | ✅ |
sketch-animated-gif-koral | KoralGifDecoderProvider | KoralGifDecoder | ✅ | ❌ | ❌ | ❌ |
sketch-animated-webp | AnimatedWebpDecoderProvider | android api 28+: ImageDecoderAnimatedWebpDecoder android api 27-: Not supported non android: SkiaAnimatedWebpDecoder |
✅(API 28) | ✅ | ✅ | ✅ |
sketch-animated-heif | ImageDecoderAnimatedHeifDecoderProvider | ImageDecoderAnimatedHeifDecoder | ✅(API 30) | ❌ | ❌ | ❌ |
Tip
The webp animation decoder that comes with the sketch-animated-webp module does not support android api 27 and below. If necessary, please refer to PenfeizhouAnimatedWebpDecoder in the sample and combine it with the https://github.com/penfeizhou/APNG4Android library for android Supported by api 27 and below
Before loading animations, you need to select one of the above components and configure
dependencies. Take sketch-animated-gif
as an example:
${LAST_VERSION}
: (Not included 'v')
implementation("io.github.panpf.sketch4:sketch-animated-gif:${LAST_VERSION}")
Important
The above components all support automatic registration. You only need to import them without additional configuration. If you need to register manually, please read the documentation: 《Register component》
Simply specify the uri to load the image, as follows:
val imageUri = "https://www.sample.com/image.gif"
// compose
AsyncImage(
uri = imageUri,
contentDescription = "photo"
)
// view
imageView.loadImage(imageUri)
The sketch-animated-core
module has some extension methods for ImageRequest and ImageOptions
for animation-related configuration, as follows:
ImageRequest(context, "https://www.example.com/image.gif") {
// Disable animation and only decode the first frame of the animation
disallowAnimatedImage()
// Configure the animation to be played repeatedly once and then stop. The default is to play in an infinite loop.
repeatCount(1)
// Monitor the animation to start and stop playing
onAnimationStart {
// ...
}
onAnimationEnd {
// ...
}
// [Only Android] Modify each frame of the animation as it is drawn
animatedTransformation { canvas: Any ->
if (canvas is androidx.compose.ui.graphics.Canvas) {
// ...
} else if (canvas is android.graphics.Canvas) {
// ...
}
}
}
Decoder related to animations uniformly returns AnimatableDrawable or AnimatablePainter. You can control playback through their start() and stop() methods, and determine the playback status through the isRunning() method.
The initial state of the animation is controlled by GenericViewTarget and GenericComposeTarget. After the animation is load into Target, the status of ImageRequest.lifecycle will be checked. If the status of lifecycle is greater than start, it will start playing. Otherwise, it will wait until lifecycle. Play again when the status changes to start
GenericViewTarget and GenericComposeTarget will listen to the start and stop of ImageRequest .lifecycle Status automatic control playback
Sketch uses skiko's Codec to decode animations on non-Android platforms, but Codec decodes slower frames closer to the end of the animation.
When the decoding time exceeds the duration of the previous frame, the user will feel that the playback is stuck. Therefore, in order to improve the smoothness of playback, Sketch supports the function of caching decoding timeout frames.
However, this feature will significantly increase memory consumption, so it is turned off by default. You can enable it through the cacheDecodeTimeoutFrame() function, as follows:
ImageRequest(context, "https://www.example.com/image.gif") {
cacheDecodeTimeoutFrame(true)
}