https://kotlinlang.org logo
#compose
Title
# compose
p

Paul

11/30/2021, 1:08 PM
Hey everyone. I'm trying to achieve a simple animation with text expanding and collapsing. However, I've stumbled across the problem I'm not sure how to solve. Thread 👇
The code:
Copy code
@Composable
internal fun GameSummary(summary: String) {
    var isExpanded by remember { mutableStateOf(false) }
    var isExpandable by remember { mutableStateOf(true) }
    val cardClickableModifier = if (isExpandable || isExpanded) {
        Modifier.clickable(
            onClick = { isExpanded = !isExpanded },
        )
    } else {
        Modifier
    }

    Card(
        modifier = Modifier
            .fillMaxWidth()
            .animateContentSize(
                animationSpec = tween(durationMillis = ANIMATION_DURATION)
            )
            .then(cardClickableModifier),
    ) {
        Column(modifier = Modifier.fillMaxWidth()) {
            // Title (not relevant)
            Text(
                text = stringResource(R.string.game_summary_title),
                modifier = ...,
            )
            Text(
                text = summary,
                modifier = Modifier
                    .padding(horizontal = 15.dp)
                    .padding(bottom = 15.dp),
                overflow = TextOverflow.Ellipsis,
                maxLines = if (isExpanded) Integer.MAX_VALUE else 4,
                onTextLayout = { textLayoutResult ->
                    isExpandable = textLayoutResult.didOverflowHeight
                }
            )
        }
    }
}
The expected behavior I'm trying to achieve:
The actual behavior I'm having:
As you see, expanding works correctly. However, when animating from the expanded state back to collapsed, the current behavior just simply snaps back to the collapsed height. This is due to the fact that my code utilizes the
maxLines
parameter of the
Text
composable. What is the best way to achieve the desired behavior? @Doris Liu
d

Doris Liu

11/30/2021, 7:41 PM
animateContentSize
doesn't retain the old content, therefore during collapsing you are seeing the new shorter text right away while the resizing is happening. To achieve what's shown in the first video, you'd need to use
AnimatedContent
to swap between full text and collapsed text. Here's an example of swapping text based on target states using AnimatedContent: https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:compose/[…]oidx/compose/animation/samples/AnimatedContentSamples.kt;l=64 Note, you'll also need to customize the enter/exit transition for the text so that the collapsed text exits immediately (i.e. ExitTransition.None), and enters after the size animation has finished.
2 Views