Start native apps faster with the Composables CLI ->
API Reference Item

NavDisplay.PopTransitionKey

The key for NavEntry.metadata or Scene.metadata to notify the NavDisplay of how the content should be animated when popping from backstack.

SceneOverrideEntryTransitionsSample

@Sampled
@Composable
fun SceneOverrideEntryTransitionsSample() {
    val backStack = rememberNavBackStack(A)
    NavDisplay(
        backStack,
        onBack = { backStack.removeLastOrNull() },
        entryDecorators = listOf(rememberSaveableStateHolderNavEntryDecorator()),
        // the Scene overrides the NavEntry's slide vertical with slide horizontal transitions
        sceneStrategies = listOf(SceneOverrideEntryTransitionsSceneStrategy()),
        entryProvider =
            entryProvider {
                entry<A> { BlueBox("A") { backStack.add(B) } }
                // the entry defines slide vertical transitions
                entry<B>(
                    metadata =
                        metadata {
                            put(NavDisplay.TransitionKey) { slideVertical }
                            put(NavDisplay.PopTransitionKey) { slideVertical }
                            put(NavDisplay.PredictivePopTransitionKey, { _: Int -> slideVertical })
                        }
                ) {
                    RedBox("B")
                }
            },
    )
}

private class SceneOverrideEntryTransitionsSceneStrategy<T : Any>() : SceneStrategy<T> {
    override fun SceneStrategyScope<T>.calculateScene(entries: List<NavEntry<T>>): Scene<T>? {
        if (entries.isEmpty()) return null
        return SceneOverrideEntryTransitionsScene(entries.last(), entries.dropLast(1))
    }
}

private class SceneOverrideEntryTransitionsScene<T : Any>(
    val currentEntry: NavEntry<T>,
    override val previousEntries: List<NavEntry<T>>,
) : Scene<T> {
    override val key = currentEntry.contentKey
    override val entries: List<NavEntry<T>> = listOf(currentEntry)
    override val content: @Composable (() -> Unit) = { currentEntry.Content() }
    // super.metadata defaults to [entries.last()]'s metadata
    // so this overrides the last entry's transitions
    override val metadata: Map<String, Any> = super.metadata + sceneTransitions
}

private val sceneTransitions = metadata {
    put(NavDisplay.TransitionKey) { slideHorizontal }
    put(NavDisplay.PopTransitionKey) { slideHorizontal }
    put(NavDisplay.PredictivePopTransitionKey) { slideHorizontal }
}

private val duration = 5000
private val animSpec: FiniteAnimationSpec<IntOffset> =
    tween(duration, easing = LinearOutSlowInEasing)
private val slideHorizontal =
    slideInHorizontally(animSpec) { it / 2 } togetherWith slideOutHorizontally(animSpec) { -it / 2 }
private val slideVertical =
    slideInVertically(animSpec) { it / 2 } togetherWith slideOutVertically(animSpec) { -it / 2 }