What You Will Build

A transition showcase screen with four different enter/exit animation styles - Slide, Scale, Rotate (fade+scale), and Fade+Slide - switchable via filter chips. A toggle button shows and hides a content box using the selected transition. This teaches you the full vocabulary of Compose enter/exit transitions.

Why Understanding Transitions Is Fundamental

Every app needs show/hide animations: dialogs appearing, snackbars sliding in, bottom sheets expanding, content loading. Compose provides a rich set of enter/exit transitions through AnimatedVisibility, and understanding how to combine them with the + operator unlocks any animation you need.

Key Compose Concepts

  • AnimatedVisibility with custom enter/exit specs.
  • slideInHorizontally, scaleIn, fadeIn, slideInVertically and their exit counterparts.
  • Combining transitions with the + operator.
  • FilterChip for selecting between transition types.

Step 1: State and Transition Types

var transitionType by remember { mutableIntStateOf(0) }
var show by remember { mutableStateOf(true) }
val types = listOf("Slide", "Scale", "Rotate", "Fade+Slide")

Step 2: Filter Chip Selector

Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
    types.forEachIndexed { i, t ->
        FilterChip(
            selected = i == transitionType,
            onClick = { transitionType = i },
            label = { Text(t) }
        )
    }
}

Step 3: AnimatedVisibility with Dynamic Transitions

AnimatedVisibility(
    visible = show,
    enter = when (transitionType) {
        0 -> slideInHorizontally { -it }
        1 -> scaleIn()
        2 -> fadeIn() + scaleIn()
        else -> slideInVertically { it } + fadeIn()
    },
    exit = when (transitionType) {
        0 -> slideOutHorizontally { it }
        1 -> scaleOut()
        2 -> fadeOut() + scaleOut()
        else -> slideOutVertically { -it } + fadeOut()
    }
) {
    Box(
        Modifier
            .size(200.dp)
            .clip(RoundedCornerShape(24.dp))
            .background(Color(0xFF4ECDC4)),
        contentAlignment = Alignment.Center
    ) {
        Text("Content", color = Color.White,
            style = MaterialTheme.typography.headlineMedium)
    }
}

Button(onClick = { show = !show }) {
    Text(if (show) "Hide" else "Show")
}

The Full Transition Vocabulary

Here is a reference for all built-in Compose enter/exit transitions:

  • fadeIn() / fadeOut() - Opacity transition
  • slideInHorizontally { } / slideOutHorizontally { } - Horizontal slide (lambda returns initial/target offset)
  • slideInVertically { } / slideOutVertically { } - Vertical slide
  • scaleIn() / scaleOut() - Scale from/to zero
  • expandIn() / shrinkOut() - Clip-based size transition
  • expandHorizontally() / shrinkHorizontally() - Width-only clip transition
  • expandVertically() / shrinkVertically() - Height-only clip transition

Tips and Pitfalls

  • Combine with + operator: fadeIn() + scaleIn() runs both animations simultaneously for richer effects.
  • Lambda parameter in slide transitions receives the full size and returns the offset. Use { -it } for left/top and { it } for right/bottom.
  • Custom animation specs: Pass animationSpec = tween(300) or spring() to any transition for timing control.
  • AnimatedVisibility removes the composable from the tree when not visible, unlike Modifier.alpha(0f) which keeps it in the layout.

Minimum SDK: API 24+ with Compose BOM 2024.01+

Get New Tutorials by Email

No spam. Just clear, practical breakdowns you can apply right away.

Enjoy this tutorial?

Get new practical tech tutorials in your inbox.