Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Long press gesture in Jetpack Compose

How to get this content size reduce animation with jetpack compose when long pressed and then get normal when released(like the card in Spotify Android App).

Here is a gif showing the animation.

Spotify Card

like image 932
sunny52525 Avatar asked Oct 14 '25 14:10

sunny52525


1 Answers

You can use a Transition to manage the animations between the pressed and release states.

enum class ComponentState { Pressed, Released }

var toState by remember { mutableStateOf(ComponentState.Released) }
val transition: Transition<ComponentState> = updateTransition(targetState = toState, label = "")

// Defines a float animation to scale x,y
val scalex: Float by transition.animateFloat(
    transitionSpec = { spring(stiffness = 50f) }, label = ""
) { state ->
    if (state == ComponentState.Pressed) 0.90f else 1f
}
val scaley: Float by transition.animateFloat(
    transitionSpec = { spring(stiffness = 50f) }, label = ""
) { state ->
    if (state == ComponentState.Pressed) 0.90f else 1f
}

Then you can use the PointerInputScope.detectTapGestures to detect the press gestures:

val modifier = Modifier.pointerInput(Unit) {
    detectTapGestures(
        onPress = {
            toState = ComponentState.Pressed
            tryAwaitRelease()
            toState = ComponentState.Released
        }
    )
}

Finally apply the animation to your Composable.
For example:

Box(
    modifier
        .width((100 * scalex).dp)
        .height((100 * scaley).dp),
    contentAlignment = Alignment.Center) {

    Image(
        //...
        modifier = Modifier.graphicsLayer{
            scaleX = scalex;
            scaleY = scaley
        })
}

enter image description here

like image 198
Gabriele Mariotti Avatar answered Oct 17 '25 03:10

Gabriele Mariotti