An Exploration of the Internal Mechanism of Crossfade Composable
An Exploration of the Internal Mechanism of Crossfade Composable
In Jetpack Compose, Crossfade provides a simple and declarative way to animate the transition between two different UI states. When the targetState passed to it changes, it smoothly fades out the old content while simultaneously fading in the new content. While its public API is minimal, a study of its internal source code reveals a sophisticated state machine that manages the lifecycle of both the incoming and outgoing composables, orchestrates their animations, and ensures a seamless visual transition.
The entire mechanism is built upon the foundational Transition API, which is the core engine for state-based animations in Compose.
The Entry Point: Crossfade(targetState, ...)
The most common Crossfade function that developers use is a simple wrapper. Its entire purpose is to create and manage a Transition object for you.
@Composable
public fun <T> Crossfade(
targetState: T,
// ... modifier, animationSpec
content: @Composable (T) -> Unit,
) {
// 1. Create a Transition that tracks changes to targetState.
val transition = updateTransition(targetState, label)
// 2. Delegate to the more powerful Transition.Crossfade extension.
transition.Crossfade(modifier, animationSpec, content = content)
}
updateTransition(targetState): This is the key. It creates aTransitionobject that is aware of thetargetState. Whenever thetargetStatevalue changes across recompositions, thisTransitionobject will animate from itscurrentStateto the newtargetState.- Delegation: It then immediately calls an extension function on this
Transitionobject,transition.Crossfade(...), which contains the actual implementation logic.
This article continues for subscribers
Subscribe to Dove Letter for full access to 40+ deep-dive articles about Android and Kotlin development.
Become a Sponsor