have started to play around with MotionLayout but ...
# compose
a
have started to play around with MotionLayout but getting a lot of jank when using it with LazyColumn so wondering whether what I'm doing wrong. Basically I'm creating a collapsible style header style, but have simplified the code down for the purposes here, so I have a box to represent the header with the rest of the screen taken up as a LazyColumn. With only a handful of items (simply
Text
) in the list the animation becomes jerky. In comparison, having only the button in the list the animation is relatively smooth. (Videos attached) (Code and videos in thread)
🧵 1
Copy code
@Composable
fun MotionLayoutScreen() {
    val animateToEnd = remember {
        mutableStateOf(false)
    }

    val startSet = ConstraintSet {
        val header = createRefFor("header")
        val list = createRefFor("list")

        constrain(header) {
            start.linkTo(parent.start)
            end.linkTo(parent.end)
            top.linkTo(<http://parent.top|parent.top>)
            bottom.linkTo(<http://list.top|list.top>)

            height = Dimension.value(300.dp)
            width = Dimension.fillToConstraints
        }

        constrain(list) {
            start.linkTo(parent.start)
            end.linkTo(parent.end)
            top.linkTo(header.bottom)
            bottom.linkTo(parent.bottom)
            height = Dimension.fillToConstraints
            width = Dimension.fillToConstraints
        }

    }

    val endSet = ConstraintSet {
        val header = createRefFor("header")
        val list = createRefFor("list")

        constrain(header) {
            start.linkTo(parent.start)
            end.linkTo(parent.end)
            top.linkTo(<http://parent.top|parent.top>)
            bottom.linkTo(<http://list.top|list.top>)

            height = Dimension.value(40.dp)
            width = Dimension.fillToConstraints
        }

        constrain(list) {
            start.linkTo(parent.start)
            end.linkTo(parent.end)
            top.linkTo(header.bottom)
            bottom.linkTo(parent.bottom)
            height = Dimension.fillToConstraints
            width = Dimension.fillToConstraints
        }
    }

    val progress = animateFloatAsState(
        targetValue = if (animateToEnd.value) 1f else 0f,
        animationSpec = tween(2500)
    )

    MotionLayout(
        start = startSet, end = endSet, progress = progress.value,
        modifier = Modifier.fillMaxSize()
    ) {
        Box(
            modifier = Modifier
                .background(Color.Gray)
                .layoutId("header")
        )

        LazyColumn(modifier = Modifier.layoutId("list")) {
            item {
                Button(
                    onClick = { animateToEnd.value = animateToEnd.value.not() },
                ) {
                    Text("Animate")
                }
            }

            items((1..30).toList()) {
                Text(it.toString())
            }
        }
    }
}
Jank with 30 items
Smoother with just the button
to see if it would make a difference, i did also try having the items keyed... didn't seem to make a difference though
Copy code
items(items = (1..30).toList(), key = { it }) {
    Text(it.toString())
}