How to handle a long click event on wear compose?

62 Views Asked by At

I use the Wear Compose Version 1.2.1, which can handle onLongClick event with Modifier.combinedClickable(), but after the Wear Compose Version 1.3.x does not handle the long click event.

I think the feature has changed, but I don't know how to modify my code. Can anyone please suggest how can I convert the below-mentioned code for the Wear Compose Version 1.2.1,

Button(
    modifier = Modifier
        .height(48.dp)
        .width(48.dp)
        .padding(2.dp)
        .background(color = Color.Black)
        .combinedClickable(
            interactionSource = remember {
                MutableInteractionSource()
            },
            indication = null,
            enabled = true,
            onClick = {
                Toast.makeText(
                    context,
                    context.getString(R.string.long_press_to_stop),
                    Toast.LENGTH_SHORT
                ).show()
            },
            onLongClick = {
                Log.v("STOP", "onLongClick")
                // --- stop action ---
            },
        ),
    onClick = { },
    colors = ButtonDefaults.primaryButtonColors(backgroundColor =  Color.Black),
    enabled = true
) {
    Icon(
        painter = painterResource(id = R.drawable.baseline_stop_24),
        contentDescription = "Stop",
        tint = Color.LightGray
    )
}

The dependency section of my build.gradle.kts, just change the version number, then change the behaviour.

//val wearComposeVersion = "1.2.1"           // works OK
val wearComposeVersion = "1.3.0"             // does not handle long click event
implementation("androidx.wear.compose:compose-material:$wearComposeVersion")
implementation("androidx.wear.compose:compose-foundation:$wearComposeVersion")
implementation("androidx.wear.compose:compose-navigation:$wearComposeVersion")
1

There are 1 best solutions below

0
Gustavo Pagani On BEST ANSWER

Solution

In a nutshell:

  1. Add a Box as the root content of the Button.
  2. Add the combinedClickable modifier to the Box, with the onLongClick.
  3. clearAndSetSemantics from Button in order to add onLongClick for accessibility.
    val interactionSource = remember { MutableInteractionSource() }
    val enabled = true
    val onClick = { /* your code */ }
    val onLongClick = { /* your code */ }
    Button(
        onClick = onClick,
        modifier = Modifier
            .size(DefaultButtonSize)
            .clearAndSetSemantics {
                role = Role.Button
                this.contentDescription = contentDescription
                if (!enabled) {
                    disabled()
                }
                this.onClick(action = {
                    onClick()
                    true
                })
                if (onLongClick != null) {
                    this.onLongClick(action = {
                        onLongClick()
                        true
                    })
                }
            },
        enabled = enabled,
        interactionSource = interactionSource,
    ) {
        Box(
            modifier = Modifier
                .fillMaxSize()
                .clip(CircleShape)
                .combinedClickable(
                    interactionSource = interactionSource,
                    indication = null, // From material Button
                    enabled = enabled,
                    onClick = onClick,
                    onLongClick = onLongClick,
                    role = Role.Button,
                ),
        ) {
            // your content here
        }
    }

You can see how it was done in Button.

Alternative solution

Use Button component from Horologist Compose Material library.

Dependency:

implementation "com.google.android.horologist:horologist-compose-material:<version>"

Import:

import com.google.android.horologist.compose.material.Button

Usage:

Button(
    id = R.drawable.baseline_stop_24,
    contentDescription = "Stop",
    onClick = { /* your code */ },
    onLongClick = { /* your code */ },
)

Context

Wear Compose Version 1.3.x does not handle the long click event.

Yes, as per findings of a member of the Wear Compose team:

it's not possible to add now another clickable outside of the component ( eg extend Chip or Button externally and add other callbacks like LongClick) - for that we have to rewrite the component itself ( by using combinedClickable or other modifiers) .

Be mindful that the solution above is tailored for Button component. There are more steps for other components with inner paddings like Chip and Card as per this comment.