· 3 min read Posted by Gustavo Fão Valvassori
Compose Multiplatform + Lottie Animations
Animations are one key feature that provides a good user experience. Lottie, developed by Airbnb, is a great choice for adding amazing animations to your app.
Lottie implements a render engine for the Adobe After Effects animations using the Bodymovin plugin. Long story short, Bodymovin converts the After Effects animation into a JSON file that can be used by other sources (like Android, iOS, and Web apps).
Unfortunately, the Airbnb libraries do not support Compose Multiplatform. In an issue from Compose Android, they mention that their implementation is tied to the Android platform. Therefore, making it work with Kotlin Multiplatform is not in their scope.
To support this need, the community has developed a few libraries to support this use case. The most common are Kottie and Compottie.
This isn’t just theoretical. Touchlab is putting Compose Multiplatform (CMP) with Lottie into production with our clients. If you want to explore CMP in a greenfield project or integrate it into an existing app, Touchlab has the tools and expertise you need to be successful.
Start A Conversation Today!Kottie
Kottie is the first alternative. It is maintained by Ismail Mohamed and is a wrapper for the Lottie libraries implemented by Airbnb. Its usage is quite simple. All you need to do is load your JSON file as a string and use the rememberKottieComposition compose method.
// Original Code: https://github.com/ismai117/kottie/blob/55ea950751e0f337e0a0e51be527f8f5ab73723f/sample/shared/src/commonMain/kotlin/App.kt
@Composable
fun App(
modifier: Modifier = Modifier,
) {
var animation by remember { mutableStateOf("") }
// Load animation JSON
LaunchedEffect(Unit){
animation = Res.readBytes("files/animation.json").decodeToString()
}
// Create the animation composition
val composition = rememberKottieComposition(
spec = KottieCompositionSpec.File(animation)
)
// Optionally: Define the animation state so you can control the progress
val animationState by animateKottieCompositionAsState(
composition = composition,
iterations = KottieConstants.IterateForever
)
MaterialTheme {
Box(
modifier = modifier
.fillMaxSize()
.background(Color.Red),
contentAlignment = Alignment.Center
) {
// Render your Lottie file
KottieAnimation(
composition = composition,
progress = { animationState.progress },
modifier = modifier
.fillMaxWidth()
)
}
}
}
Compottie
The second option is developed by Alexander Zhirkevich. It started as a similar solution to Kottie where it used to wrap the the Lottie animation, but in the 2.0 version they are building their own renderer.
This new render works fully in Kotlin Multiplatform and is still experimental. With the shared render, you remove the complexity during installation and makes it work “natively” to Compose Multiplatform, without any bridges. Therefore, you may find issues as it’s still in development.
The usage is really simple. Just create the Compottie Composition that will hold your animation JSON instance. Then create a Compottie painter using the rememberLottiePainter
and voilà.
// Original Code: https://github.com/alexzhirkevich/compottie/blob/standalone-main/example/shared/src/commonMain/kotlin/lottiefiles/LottieFilesScreen.kt
@Composable
private fun LottieCard(
file : LottieFile,
onClick : () -> Unit,
modifier: Modifier = Modifier
) {
val composition by rememberLottieComposition {
LottieCompositionSpec.Url(file.lottieSource ?: file.jsonSource ?: "")
}
Image(
modifier = Modifier.fillMaxSize(),
painter = rememberLottiePainter(
composition = composition,
iterations = Compottie.IterateForever
),
contentDescription = file.name
)
}
Final Thoughts
The KMP community is growing fast and implementing amazing solutions for the problems we encounter. Lottie animations is one of them and it’s great to see it working with Compose Multiplatform.
The right library will very much depend on your context and needs, and both alternatives have great support and may be able to support your scenario.