Jetpack Compose Long Press Button

It took me a bit to figure this out, so I’m posting it here with the hope that it’ll save you some time! 🙂

So, what do we need?

• A custom Modifier

• A custom Button

We could implement all of this within the custom Button itself, but I think separating them is cleaner. It keeps things simpler and leaves the door open for more customizations down the road.

    Custom Modifier

    @Composable
    fun Modifier.customClickable(
        interactionSource: MutableInteractionSource?,
        onClick: () -> Unit,
        onLongClick: () -> Unit
    ): Modifier {
        val viewConfiguration = LocalViewConfiguration.current
    
        LaunchedEffect(interactionSource) {
            var isLongClick = false
    
            interactionSource?.interactions?.collectLatest { interaction ->
                when (interaction) {
                    is PressInteraction.Press -> {
                        isLongClick = false
                        delay(viewConfiguration.longPressTimeoutMillis)
                        isLongClick = true
                        onLongClick()
                    }
    
                    is PressInteraction.Release -> {
                        if (isLongClick.not()) {
                            onClick()
                        }
                    }
                }
            }
        }
    
        return this
    }

    Custom Button

    @Composable
    fun LongPressButon(
        modifier: Modifier = Modifier,
        onClick: () -> Unit,
        onLongClick: () -> Unit = {},
        enabled: Boolean = true,
        shape: Shape = ButtonDefaults.shape,
        colors: ButtonColors = ButtonDefaults.buttonColors(),
        elevation: ButtonElevation? = ButtonDefaults.buttonElevation(),
        border: BorderStroke? = null,
        contentPadding: PaddingValues = ButtonDefaults.ContentPadding,
        interactionSource: MutableInteractionSource? = remember { MutableInteractionSource() },
        content: @Composable RowScope.() -> Unit,
    ) {
        val modifierAdjusted = modifier.customClickable(
            interactionSource,
            onClick = onClick,
            onLongClick = onLongClick,
        )
        Button(
            onClick = onClick,
            modifier = modifierAdjusted,
            enabled = enabled,
            shape = shape,
            colors = colors,
            elevation = elevation,
            border = border,
            contentPadding = contentPadding,
            interactionSource = interactionSource,
            content = content
        )
    }
    

    Usage example:

     val context = LocalContext.current
        LongPressButon(
            onClick = {
                Toast.makeText(context, "Click", Toast.LENGTH_SHORT).show()
            },
            onLongClick = {
                Toast.makeText(context, "Long click", Toast.LENGTH_SHORT).show()
            },
        ) {
            Text(
                text = "Button",
            )
        }

    That’s it 🙂

    Happy coding!


    Leave a Reply

    This site uses Akismet to reduce spam. Learn how your comment data is processed.