Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to achieve slide in and out animation in android compose between two Views Synchronized

I know I can use the AnimatedVisibility Composable function and achieve slide-in animation for the visibility animation, but what I want to achieve is when one layout is in entering animation the other in the exit animation, something similar to the image below.

NB : I know that I should use Navigation compose for different screens and that animation between destinations is still under development, but I want to achieve this on the content of a part of screen, similar to CrossFade Animation.

enter image description here

like image 836
David Ibrahim Avatar asked Dec 05 '25 05:12

David Ibrahim


1 Answers

As you mentioned, this animation should be implemented by the Navigation Library and there's a ticket opened to that.

Having that in mind, I'm leaving my answer here and I hope it helps...

I'll break it in three parts:

  1. The container:
@Composable
fun SlideInAnimationScreen() {
    // I'm using the same duration for all animations. 
    val animationTime = 300 

    // This state is controlling if the second screen is being displayed or not
    var showScreen2 by remember { mutableStateOf(false) }

    // This is just to give that dark effect when the first screen is closed...
    val color = animateColorAsState(
        targetValue = if (showScreen2) Color.DarkGray else Color.Red,
        animationSpec = tween(
            durationMillis = animationTime,
            easing = LinearEasing
        )
    )
    Box(Modifier.fillMaxSize()) {
       // Both Screen1 and Screen2 are declared here...
    }
}
  1. The first screen just do a small slide to create that parallax effect. I'm also changing the background color from Red to Dark just to give this overlap/hide/dark effect.
// Screen 1
AnimatedVisibility(
    !showScreen2,
    modifier = Modifier.fillMaxSize(),
    enter = slideInHorizontally(
        initialOffsetX = { -300 }, // small slide 300px
        animationSpec = tween(
            durationMillis = animationTime, 
            easing = LinearEasing // interpolator
        )
    ),
    exit = slideOutHorizontally(
        targetOffsetX = { -300 }, =
        animationSpec = tween(
            durationMillis = animationTime, 
            easing = LinearEasing
        )
    )
) {
    Box(
        Modifier
            .fillMaxSize()
            .background(color.value) // animating the color
    ) {
        Button(modifier = Modifier.align(Alignment.Center),
            onClick = {
                showScreen2 = true
            }) {
            Text(text = "Ok")
        }
    }
}
  1. The second is really sliding from the edges.
// Screen 2
AnimatedVisibility(
    showScreen2,
    modifier = Modifier.fillMaxSize(),
    enter = slideInHorizontally(
        initialOffsetX = { it }, // it == fullWidth
        animationSpec = tween(
            durationMillis = animationTime, 
            easing = LinearEasing
        )
    ),
    exit = slideOutHorizontally(
        targetOffsetX = { it },
        animationSpec = tween(
            durationMillis = animationTime, 
            easing = LinearEasing
        )
    )
) {
    Box(
        modifier = Modifier
            .fillMaxSize()
            .background(Color.Blue)
    ) {
        Button(modifier = Modifier.align(Alignment.Center),
            onClick = {
                showScreen2 = false
            }) {
            Text(text = "Back")
        }
    }
}

Here is the result:

enter image description here

like image 82
nglauber Avatar answered Dec 06 '25 19:12

nglauber



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!