Exploring Jetpack Compose Animation Specs: Spring, Tween, Snap, Keyframes, Repeatable and Infinite Repeatable
This article provides a comprehensive tutorial on Jetpack Compose animation specifications, covering Spring, Tween, Snap, Keyframes, repeatable and infinite repeatable specs, explaining their parameters, default values, and demonstrating practical Kotlin code examples with visual GIFs to illustrate each effect.
This article is the fourth in a series about animation techniques in Jetpack Compose. It begins by introducing the AnimationSpec interface, which stores animation specifications such as the data type to animate and the configuration used during the animation.
interface AnimationSpec
{
fun
vectorize(
converter: TwoWayConverter
): VectorizedAnimationSpec
}The article then dives into the most commonly used animation specs, starting with Spring . The spring function returns a SpringSpec and accepts three parameters— dampingRatio , stiffness , and visibilityThreshold —all of which have sensible defaults.
@Stable
fun
spring(
dampingRatio: Float = Spring.DampingRatioNoBouncy,
stiffness: Float = Spring.StiffnessMedium,
visibilityThreshold: T? = null
): SpringSpec
=
SpringSpec(dampingRatio, stiffness, visibilityThreshold)The Spring object defines a set of constant values for damping ratios and stiffness levels, such as StiffnessMedium and DampingRatioNoBouncy . Several code snippets demonstrate how changing these values affects the animation of a Box color or size.
val blue = remember { mutableStateOf(true) }
val color by animateColorAsState(
if (blue.value) Blue else Red,
animationSpec = spring(
dampingRatio = Spring.DampingRatioNoBouncy,
stiffness = Spring.StiffnessMedium
)
)Next, the Tween spec is introduced. tween creates a TweenSpec with configurable duration, delay, and easing curve. The article explains the three parameters and shows how to use built‑in easing functions like FastOutSlowInEasing , LinearEasing , FastOutLinearInEasing , and LinearOutSlowInEasing .
fun
tween(
durationMillis: Int = DefaultDurationMillis,
delayMillis: Int = 0,
easing: Easing = FastOutSlowInEasing
): TweenSpec
= TweenSpec(durationMillis, delayMillis, easing)The Snap spec instantly jumps to the target value after an optional delay. Its implementation is a thin wrapper around SnapSpec , which implements DurationBasedAnimationSpec .
fun
snap(delayMillis: Int = 0) = SnapSpec
(delayMillis)
class SnapSpec
(val delay: Int = 0) : DurationBasedAnimationSpec
{
override fun
vectorize(
converter: TwoWayConverter
): VectorizedDurationBasedAnimationSpec
= VectorizedSnapSpec(delay)
}The Keyframes spec allows defining values at specific timestamps, optionally with easing for each segment. The article shows the DSL using the infix at and with operators.
fun
keyframes(
init: KeyframesSpec.KeyframesSpecConfig
.() -> Unit
): KeyframesSpec
{
return KeyframesSpec(KeyframesSpec.KeyframesSpecConfig
().apply(init))
}
class KeyframesSpecConfig
{
var durationMillis: Int = DefaultDurationMillis
var delayMillis: Int = 0
internal val keyframes = mutableMapOf
>()
infix fun T.at(timeStamp: Int): KeyframeEntity
{
return KeyframeEntity(this).also { keyframes[timeStamp] = it }
}
infix fun KeyframeEntity
.with(easing: Easing) { this.easing = easing }
}For repeating animations, the article covers repeatable and infiniteRepeatable . repeatable takes an iteration count, an inner DurationBasedAnimationSpec , a RepeatMode (Restart or Reverse), and an optional start offset. infiniteRepeatable omits the iteration count.
fun
repeatable(
iterations: Int,
animation: DurationBasedAnimationSpec
,
repeatMode: RepeatMode = RepeatMode.Restart,
initialStartOffset: StartOffset = StartOffset(0)
): RepeatableSpec
=
RepeatableSpec(iterations, animation, repeatMode, initialStartOffset)
fun
infiniteRepeatable(
animation: DurationBasedAnimationSpec
,
repeatMode: RepeatMode = RepeatMode.Restart,
initialStartOffset: StartOffset = StartOffset(0)
): InfiniteRepeatableSpec
=
InfiniteRepeatableSpec(animation, repeatMode, initialStartOffset)Throughout the article, GIFs illustrate how each spec behaves with different parameter values, helping readers visualize the impact of damping, stiffness, duration, delay, and easing on UI animations.
In summary, Jetpack Compose provides a rich set of animation specifications—Spring, Tween, Snap, Keyframes, repeatable, and infinite repeatable—each customizable via Kotlin APIs. Understanding these specs enables developers to create fluid, responsive, and expressive UI animations on Android.
Rare Earth Juejin Tech Community
Juejin, a tech community that helps developers grow.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.