Hello! I'm zm soft, a developer who registered in late 2023 and started publishing apps. I'm also planning to release a developer app — check it out when it launches.
Do you use animations in your apps? Even a small animation can make an app feel clearer and more polished. Today I want to write about adding animation to Android apps.
LottieAnimation
I use LottieAnimation, an animation display library. I chose it because it makes adding lightweight animations relatively simple.
What Animations Are Available
One of the best things about this library is the huge selection of animations available for free. You can browse them on the LottieFiles website. There are plenty of paid options too, but filtering by free is more than enough for most use cases.
I don't have the skills or energy to create animations from scratch, so whenever I need something animated, I start by seeing what's available on this site. For example, using a "tap here" animation on first launch is a great way to guide users to clickable areas. I've actually used an animation like this to show users how to interact with my app.
The Appeal Is Simplicity
Implementation is straightforward. If you just need to display an animation in a fixed layout, this is all you need — no logic required:
Basic Lottie Implementation
Lottie is extremely simple to implement. Just embed it in your layout and it works with no additional logic.
Example:
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/lottie_id"
app:lottie_rawRes="@raw/your_lottie_animation"/>
How to Use Lottie
Here's the general workflow:
- Add the library (update
build.gradle) - Get and place the animation file
- Configure the layout file
- Customize the animation
Implementation with Code
Adding the library to build.gradle:
First, add the library to make Lottie available. Use the latest version unless you have compatibility concerns.
dependencies {
implementation 'com.airbnb.android:lottie:3.4.0'
}
Placing the animation file:
Download your animation file (.json) from LottieFiles and place it in your app's res/raw folder.
Configuring the layout:
Add LottieAnimationView to your XML layout and reference the animation file you downloaded.
Customizing the animation:
You can customize animation behavior as needed:
- Enable or disable looping
- Set the number of loops
- Set the playback speed (including reverse playback)
With dynamic control, you can play/pause at any time or change the speed programmatically.
For static configuration, the following attributes control animation behavior:
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/lottie_id"
android:scaleType="centerCrop"
app:lottie_autoPlay="true"
app:lottie_loop="true"
app:lottie_speed="0.15"
app:lottie_rawRes="@raw/your_lottie_animation"/>
This example auto-plays your_lottie_animation.json in a loop at 0.15× speed.
For dynamic control:
lottieAnimationView.playAnimation()
You can also add a listener to detect when an animation ends:
lottieAnimationView.addAnimatorListener(object : Animator.AnimatorListener {
override fun onAnimationStart(animation: Animator) {
// Called when animation starts
}
override fun onAnimationEnd(animation: Animator) {
// Called when animation ends
}
override fun onAnimationCancel(animation: Animator) {
// Called when animation is cancelled
}
override fun onAnimationRepeat(animation: Animator) {
// Called when animation repeats
}
})
Caveats and Troubleshooting
Lottie is very useful, but there are a few things to watch out for. Object repositioning doesn't always work as expected. Here are two real issues I ran into.
Troubleshooting example 1:
I caused a stack overflow in how I handled the end-of-animation event. Specifically, I had set up forward and reverse playback to alternate — and calling the next play directly from within the callback created infinite recursion. The fix was to post to the main thread instead of calling it directly:
lottieAnimationView.addAnimatorListener(object : Animator.AnimatorListener {
override fun onAnimationStart(animation: Animator) {
// Called when animation starts
}
override fun onAnimationEnd(animation: Animator) {
lottieAnimationView.speed = lottieAnimationView.speed*(-1) // reverse direction
lottieAnimationView.post {
// Post to avoid stack overflow from direct recursive call
if(isAttachedToWindow) {
lottieAnimationView.playAnimation()
}
}
}
override fun onAnimationCancel(animation: Animator) {
// Called when animation is cancelled
}
override fun onAnimationRepeat(animation: Animator) {
// Called when animation repeats
}
})
Troubleshooting example 2:
You also need to handle onPause. You should stop animations in the background to avoid unnecessary processing:
override fun onResume(owner: LifecycleOwner) {
super.onResume(owner)
lottieAnimationView.playAnimation()
}
override fun onPause(owner: LifecycleOwner) {
lottieAnimationView.cancelAnimation()
super.onPause(owner)
}
However, if you're doing anything on animation end events, this alone isn't enough. You'll also need to check whether the parent view is still attached before triggering anything:
if(isAttachedToWindow) {
binding.lottieBackground.playAnimation()
}
Summary
Lottie is a powerful tool for improving your app's UI. It has a huge selection of free animations and the implementation is simple. Understand the edge cases, handle them appropriately, and you'll get a lot out of it. The occasional gotcha aside, it's an excellent library overall — with plenty of free resources available. Definitely worth trying if you want to make your app look better.