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!