Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to animate width of a button in Jetpack Compose

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.

like image 679
Kélian Avatar asked Jun 14 '20 18:06

Kélian


2 Answers

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()
        )
    }
}
like image 165
Doris Liu Avatar answered Oct 16 '22 17:10

Doris Liu


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

like image 29
Gabriele Mariotti Avatar answered Oct 16 '22 18:10

Gabriele Mariotti