Introduction to Animations in Jetpack Compose

Rafael Meneghelo
3 min readApr 24, 2023

--

Hello there, my fellow Kotlin enthusiasts!

Animations can make your app more interactive and delightful. With Jetpack Compose, you can create animations in a simple and efficient way. Animations in Compose are declarative and reactive, which means you can easily control the animation’s behavior and properties based on the state of your app.

In this tutorial, we’ll explore how to create simple animations using Jetpack Compose.

Benefits of Animations in Jetpack Compose

Animations in Jetpack Compose have several benefits, including:

  • Improved user experience: Animations can make your app more engaging and interactive, improving the overall user experience.
  • Declarative and reactive: Animations in Jetpack Compose are declarative, meaning you can define the animation’s properties and behaviour based on the current state of your app. The animations are also reactive, meaning they automatically update when the state changes.
  • Easy to use: Jetpack Compose makes it easy to create animations with just a few lines of code.

Implementing Animations in Jetpack Compose

To implement animations in Jetpack Compose, we’ll use the animate functions that are available in the animation package. These functions can be used to animate properties such as alpha, position, and scale.

Let’s take a look at a simple example of animating a box’s position on the screen.

@Composable
fun AnimatedBox() {
var position by remember { mutableStateOf(Offset.Zero) }
val targetPosition = Offset(200f, 200f)

LaunchedEffect(Unit) {
var startTime = 0L
while (true) {
val currentTime = System.currentTimeMillis()
val elapsedTime = currentTime - startTime
if (elapsedTime > 1000) break
val t = elapsedTime / 1000f
position = Offset(
x = targetPosition.x * t,
y = targetPosition.y * t
)
delay(16)
}
}

Box(
Modifier
.offset(position.x.dp, position.y.dp)
.background(Color.Red)
.size(50.dp)
.pointerInput(Unit) {
detectDragGestures { change, _ ->
position += change.positionChange()
}
}
)
}

This code is about creating an animation effect in a Composable function using Jetpack Compose. In this example, we’re animating a red box that moves from its original position (0,0) to the position (200,200) over a period of one second.

Here’s how it works:

  • First, we create a mutable variable called position which represents the current position of the box. We also define the target position where we want the box to move to.
var position by remember { mutableStateOf(Offset.Zero) }
val targetPosition = Offset(200f, 200f)
  • Next, we create a LaunchedEffect block. This block is used to launch a coroutine that will handle the animation. Inside the block, we define a loop that runs until one second has passed. In each iteration of the loop, we calculate the elapsed time since the animation started and use it to update the position of the box. We then delay the coroutine for 16 milliseconds (which is roughly 60 frames per second) to give the impression of a smooth animation.
LaunchedEffect(Unit) {
var startTime = 0L
while (true) {
val currentTime = System.currentTimeMillis()
val elapsedTime = currentTime - startTime
if (elapsedTime > 1000) break
val t = elapsedTime / 1000f
position = Offset(
x = targetPosition.x * t,
y = targetPosition.y * t
)
delay(16)
}
}
  • Finally, we create a Box Composable that uses the position variable to set the offset of the box. We also set the background color, size and add a drag gesture to the box to allow the user to move it around.
Box(
Modifier
.offset(position.x.dp, position.y.dp)
.background(Color.Red)
.size(50.dp)
.pointerInput(Unit) {
detectDragGestures { change, _ ->
position += change.positionChange()
}
}
)
Android emulator screen showing a red square at the top right of the screen. When we click and drag the square, it moves around along with the mouse.

Conclusion

Animations in Jetpack Compose are easy to implement and can make your app more engaging and interactive. By using the animate functions, you can create animations that are declarative and reactive, allowing you to control the animation's behaviour based on the state of your app.

--

--