How to animate between two layout states in Jetpack compose, similar to how MotionLayout animates constraints?

195 Views Asked by At

Using MotionLayout we can animate view constraints, such as views can be re-arranged while animating between the different "arrangements"

How can we achieve the same using Composables in jetpack compose?

I've written a quick example to help demonstrate what I'm trying to achieve.

Let's say we have an Image with a Text underneath, and when a button is clicked, we want to alter the layout in a way where the text becomes aligned to the right of the image. That's pretty simple using MotionLayout, we just define 2 layout states describing the above, with transition between them.

I can't find anything similar in compose. The code below for example will simply re-compose the view and "snap" between the 2 states rather than animate.

@Preview
@Composable
fun MainLayout(modifier: Modifier = Modifier) {
  var isVertical by remember { mutableStateOf(false) }
  Box(
    modifier = Modifier
      .fillMaxSize()
      .background(color = Color.Black)
  ) {
    Column(modifier = Modifier.fillMaxSize()) {
      Button(
        modifier = Modifier.align(Alignment.CenterHorizontally),
        onClick = { isVertical = !isVertical }) {
        Text(text = "toggle")
      }
      if (isVertical) {
        VerticalState()
      } else {
        HorizontalState()
      }
    }
  }
}

//@Preview(showBackground = true)
@Composable
fun VerticalState(modifier: Modifier = Modifier) {
  Column(
    modifier = Modifier
      .padding(top = 100.dp)
      .fillMaxWidth()
  ) {
    Image(
      modifier = Modifier.align(Alignment.CenterHorizontally),
      painter = painterResource(id = R.drawable.ic_launcher_foreground),
      contentDescription = "image"
    )
    Text(
      modifier = Modifier.align(Alignment.CenterHorizontally),
      text = "Some text",
      color = Color.White
    )
  }
}

//@Preview(showBackground = true)
@Composable
fun HorizontalState(modifier: Modifier = Modifier) {
  Row {
    Image(
      painter = painterResource(id = R.drawable.ic_launcher_foreground),
      contentDescription = "image"
    )

    Text(
      modifier = Modifier.align(Alignment.CenterVertically),
      text = "Some text",
      color = Color.White
    )
  }
}

How can I animate between VerticalState and HorizontalState? Or how do I achieve the desired effect?

0

There are 0 best solutions below