sunny52525
sunny52525

Reputation: 323

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

Upvotes: 4

Views: 4487

Answers (1)

Gabriele Mariotti
Gabriele Mariotti

Reputation: 363975

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

Upvotes: 11

Related Questions