1

Why does adding a .combinedClickable() to the modifier of a Button not do anything? The onClick will do something, but I'd expect the modifier.combinedClickable() to override the onClick behavior.

Button(
        onClick = { // does something },
        modifier = Modifier
            ...
            .combinedClickable(
                enabled = true,
                onLongClick = { // does something else },
                onClick = { // also does something else }
            ), ... ) { ... }

Even if I duplicate the Button functionality, I don't have access to all the internal classes that are in the material3 scope, and I much rather use those internals rather than create my own.

BobDidley
  • 53
  • 6

1 Answers1

3

It's because how gesture system works in Jetpack Compose. When you have 2 Modifiers that consume PointerEventChange second one won't get it with default pass.

You can check out explanation about gesture system here

https://stackoverflow.com/a/70847531/5457853

Button is a Surface and, Surface is a Box with code below.

Since it already has a clickable you won't be able set another clickable, combinedClickable or other default gestures except the ones that call awaitFirstDown(requireConsumed=false), detectDragGestures and detectTransformGestures call awaitFirstDown with requireConsumed true.

Box(
        modifier = modifier
//  You add your gesture Modifier here while clickable below exists
            .minimumInteractiveComponentSize()
            .surface(
                shape = shape,
                backgroundColor = surfaceColorAtElevation(
                    color = color,
                    elevation = absoluteElevation
                ),
                border = border,
                shadowElevation = shadowElevation
            )
            .clickable(
                interactionSource = interactionSource,
                indication = rememberRipple(),
                enabled = enabled,
                onClick = onClick
            ),
        propagateMinConstraints = true
    ) {
        content()
    }

You can copy paste source code and build your own Button but for the touch you need to write your own clickable gesture before that does not consume PointerEventInput.

Thracian
  • 43,021
  • 16
  • 133
  • 222