androidandroid-jetpack-composeandroid-jetpack-compose-animation

Box inside Column with AnimatedVisibility underneath it does not animate with the animated visibility, it just jumps into position


With the following compose code, I am able to click on the top box top bring the bottom box in and out of the bottom of the screen. But the top box which has a weight of 1f in the Column does not animate with the box inside the AnimatedVisibility, it just jumps into the final position.

    @Preview
    fun MainAnimatedPanel() {
        var visible by remember { mutableStateOf(true) }
        val density = LocalDensity.current

       Box(
           modifier = Modifier.fillMaxSize()
       ) {
           Column(
               horizontalAlignment = Alignment.CenterHorizontally
           ) {
               Box(
                   modifier = Modifier
                       .fillMaxWidth()
                       .background(Color.Yellow)
                       .weight(1f)
                       .clickable { visible = !visible }
               )

               AnimatedVisibility(
                   visible = visible,
                   enter = slideInVertically {
                       with(density) { 250.dp.roundToPx() }
                   },
                   exit = slideOutVertically {
                       with(density) { 250.dp.roundToPx() }
                   },
               ) {
                   Box(
                       modifier = Modifier
                           .fillMaxWidth()
                           .height(250.dp)
                           .background(Color.Magenta)
                   )
               }
           }
       }
    }

I tried multiple layouts and different effects inside of just Box. I also tried just animating the box on its own, but it never matched the speed of the AnimatedVisibility.


Solution

  • You are not adding any size transformation. When position transformations happen size stays as the current container.

    Adding size transformations will let your top Composable to adjust size while size of AnimatedVisibility Composable changes

    enter = slideInVertically {
        with(density) { 250.dp.roundToPx() }
    } + expandVertically(),
    exit = slideOutVertically {
        with(density) { 250.dp.roundToPx() }
    } + shrinkVertically()
    

    Result

    enter image description here

    Demo

    @Preview
    @Composable
    fun MainAnimatedPanel() {
        var visible by remember { mutableStateOf(true) }
        val density = LocalDensity.current
    
        Box(
            modifier = Modifier.fillMaxSize()
        ) {
            Column(
                horizontalAlignment = Alignment.CenterHorizontally
            ) {
                Box(
                    modifier = Modifier
                        .fillMaxWidth()
                        .background(Color.Yellow)
                        .border(2.dp, Color.Blue)
                        .weight(1f)
                        .clickable { visible = !visible }
                )
    
                AnimatedVisibility(
                    visible = visible,
                    enter = slideInVertically {
                        with(density) { 250.dp.roundToPx() }
                    } + expandVertically(),
                    exit = slideOutVertically {
                        with(density) { 250.dp.roundToPx() }
                    } + shrinkVertically(),
                ) {
                    Box(
                        modifier = Modifier
                            .border(4.dp, Color.Green)
                            .fillMaxWidth()
                            .height(250.dp)
                            .background(Color.Magenta)
                    )
                }
            }
        }
    }