Animating between Composables in Navigation with Compose

Viewed 8251

I have started trying out Navigation for compose.

I created my 2 Composables and everything is working fine.

But what I'm missing is Animations (or Transitions) between the pages. I didn't find any resources pointing out how to do it in Compose.

I know all animations are based on states in Compose, but the only thing I know is the Navigation Back Stack.

6 Answers

You can use the composable I made to show enter animation (configure preferable effects in "enter" and "exit" parameters)

fun EnterAnimation(content: @Composable () -> Unit) {
    AnimatedVisibility(
        visible = true,
        enter = slideInVertically(
            initialOffsetY = { -40 }
        ) + expandVertically(
            expandFrom = Alignment.Top
        ) + fadeIn(initialAlpha = 0.3f),
        exit = slideOutVertically() + shrinkVertically() + fadeOut(),
        content = content,
        initiallyVisible = false
    )
}

You can use it like this:

NavHost(
    navController = navController,
    startDestination = "dest1"
) {
    composable("dest1") {
        EnterAnimation {
            FirstScreen(navController)
        }
    }
    composable("dest2") {
        EnterAnimation {
            SecondScreen(navController)
        }
    }
}

Accompanist version 0.16.1 and above supports animation between destinations. Here is the article for more info.

implementation("com.google.accompanist:accompanist-navigation-animation:0.16.1")  

import com.google.accompanist.navigation.animation.AnimatedNavHost
import com.google.accompanist.navigation.animation.composable
import com.google.accompanist.navigation.animation.rememberAnimatedNavController


val navController = rememberAnimatedNavController()

AnimatedNavHost(navController, startDestination = "first") {
    composable(
        route = "first",
        enterTransition = { _, _ -> slideInHorizontally(animationSpec = tween(500)) },
        exitTransition = { _, _ -> slideOutHorizontally(animationSpec = tween(500)) }
    ) {
       FirstScreen()
    }
    composable(
        route = "second",
        enterTransition = { _, _ -> slideInHorizontally(initialOffsetX = { it / 2 }, animationSpec = tween(500)) },
        exitTransition = { _, _ -> slideOutHorizontally(targetOffsetX = { it / 2 }, animationSpec = tween(500)) }
    ) {
       SecondScreen()
    }
}

Result:

enter image description here

Due to yesterday's update (version 2.4.0-alpha05):

Navigation Compose’s NavHost now always uses Crossfades when navigating through destinations.

Related