I have a list of chips in Jetpack Compose, and I was wondering how it would be possible to detect long press events on them?
Code:
SuggestionChip(
onClick = {
onQuickPresetTapped()
},
label = {
Text(text = "${quickPreset.width}x${quickPreset.height}")
}
)
Currently I have only successfully detected simple click events, although I want the app to be able to detect long click event as well.
I have tried many Stack Overflow solutions, such as the following:
SuggestionChip(
label = {
Text(text = "${quickPreset.width}x${quickPreset.height}")
},
onClick = { },
modifier = Modifier.combinedClickable(
onClick = { onQuickPresetTapped() },
onLongClick = { onQuickPresetLongPressed() }
)
)
... which did not fix the problem.
Another thing I tried is wrapping the chip in a box with a long click and click event like so:
Box(
modifier = Modifier.combinedClickable(
onClick = { onQuickPresetTapped() },
onLongClick = { onQuickPresetLongPressed() }
)
) {
SuggestionChip(
onClick = {
onQuickPresetTapped()
},
label = {
Text(text = "${quickPreset.width}x${quickPreset.height}")
}
)
}
... this also did not solve the problem.
How can I get long press events to work on chips? I have tried many things without success.
I just came up with a solution I like quite a bit. Here's the code and I'll try to explain anything interesting afterward:
LazyRow() {
items(chipTitles.size) { i ->
val inputChipInteractionSource = remember { MutableInteractionSource() }
Box {
InputChip(
label = { Text(text = titles[i]) },
onClick = {},
interactionSource = inputChipInteractionSource,
)
Box(modifier = Modifier
.matchParentSize()
.combinedClickable (
onLongClick = { onLongPress(i) },
onClick = { onClick(i) },
interactionSource = inputChipInteractionSource,
indication = null,
))
}
}
The element that makes this work at all is Box
. We use a Box firstly as a container around an InputChip
. We then use a second Box
as something similar to scrim that lies on top of an InputChip
. The InputChip
is no longer clickable because it is underneath the scrim-like Box
. We then use the combinedClickable() Modifier
on the scrim-like Box
, which allows us to easily handle clicks and long presses. This clickable Box
can be a bit bigger than the InputChip
, which makes the interaction indication animations a little awkward.
That's where MutableInteractionSource
comes into play. MutableInteractionSource
is essentially a stream that emits when an interaction has occurred. We attach this InteractionSource
to the clickable, scrim-like Box
but with indications on this box turned off (setting it to null
). This scrim-like Box
emits interactions from our provided InteractionSource
but does not display interaction inidcation animations. At the same time, we attach this same InteractionSource
to the InputChip
. So although the InputChip
is not actually clickable (it is underneath the scrim-like Box
), it still receives a stream of interactions through the InteractionSource
and performs indication animations when expected.
Note: combinedClickable
is still tagged as @ExperimentalFoundationApi
and may be changed or removed in the future.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With