How to animate width of a button in Jetpack Compose

16.1k Views Asked by At

Let's say I have a Composable like this :

@Composable
fun LoadingButton() {
    val (isLoading, setIsLoading) = state { false }

    Button(
        onClick = setIsLoading,
        text = {
            if (isLoading) {
                Text(text = "Short text")
            } else {
                Text(text = "Very very very long text")
            }
        }
    )
}

How can I animate the width update of my button ?

I'm well aware that I could add a preferredWidth modifier to the button and animate this width with :

val buttonWidth = animate(target = if (isLoading) LoadingButtonMinWidth else LoadingButtonMaxWidth)

But this is not my what I want. I need to animate the automatic "wrap-content" width.

Thanks in advance.

2

There are 2 best solutions below

0
On BEST ANSWER

You need to add an animateContentSize modifier to the Text Composable:

@Composable
fun LoadingButton() {
    val (isLoading, setIsLoading) = state { false }
    Button(onClick = { setIsLoading(!isLoading) }) {
        Text(
            text = if (isLoading) {
               "Short text"
            } else {
                "Very very very long text"
            },
            modifier = Modifier.animateContentSize()
        )
    }
}
0
On

You can apply the modifier animateContentSize

This modifier animates its own size when its child modifier (or the child composable if it is already at the tail of the chain) changes size. This allows the parent modifier to observe a smooth size change, resulting in an overall continuous visual change.

Something like:

var isLoading by remember { mutableStateOf(false) }
val text = if (isLoading) "Short text" else "Very very very long text"

Button(onClick = { isLoading = !isLoading },
    modifier = Modifier
        .animateContentSize(
              animationSpec = tween(durationMillis = 300,
                   easing = LinearOutSlowInEasing))
) {
    Text(
        text = text,textAlign = TextAlign.Center
    )
}

enter image description here