Several ways to add click event in Jetpack Compose

There are so many ways to add click in Compose, this article makes a brief summary

1. Modifier.clickable

This is the most common and easiest way, as shown below

Box(
    modifier = Modifier.clickable {
    
    
        // 处理点击事件
    }
)

When a click occurs, in addition to corresponding event processing, it will also trigger theme effects such as water ripples (Ripple).

It should be noted that for the Composable of the Button class, it is not recommended to use Modifier.clickable, and its own onClick parameter should be used, although there are some additional processing inside it besides calling Modifier.clickable

Button (
	onClick = {
    
    
	 	// 处理点击事件
	}) {
    
    
	//...
}

2. Modifier.combinedClickable

In addition to the click event, it can handle double-click, long-press and other click events at the same time

Box(
    modifier = Modifier
        .combinedClickable(
            onClick = {
    
    
                // 单击
            },
            onDoubleClick = {
    
    
                // 双击
            },
            onLongClick = {
    
    
                // 长按
            }
        )
)

Like Modifier.clickable, clicking will trigger the water ripple effect.

3. Modifier.pointerInput

pointerInput is the entry point for processing all gesture events in Compose, similar to onTouch of traditional views. The click gesture can be recognized here, and the corresponding priority is higher than clickable, but it will not trigger effects such as water ripples

Box(
    modifier = Modifier
        .pointerInput(Unit) {
    
    
            detectTapGestures(
                onDoubleTap = {
    
    
                },
                onLongPress = {
    
    
                },
                onPress = {
    
    
                },
                onTap = {
    
    
                }
            )
        },
)

As above, detectTapGesturesyou can handle various click events. Similarly, drag events detectDragGesturescan be handled.

In addition to the corresponding events in detectTapGestures, you can also offsetget , as follows:

detectTapGestures(
    onTap = {
    
    
        val x = it.x
        val y = it.y
    },
)

In addition, when onPressthe event , you can also get the callback when the finger leaves

var pressing by remember {
    
     mutableStateOf(false) }

Box(
    modifier = Modifier
        .pointerInput(Unit) {
    
    
            detectTapGestures(
                onPress = {
    
    
                    // 按下
                    pressing = true

                    val isCanceled = tryAwaitRelease()
                    // 离开

                    pressing = false
                },
            )
        },
)

During OnPress, calling tryAwaitReleasewill suspend the current function, and continue execution when the finger leaves.

tryAwaitRelease returns a bool value: true means the finger is lifted within the current area, false means the finger has moved out of the current area. Similar to UP and CANCEL events for traditional views.

It can be seen that pointerInput can manage events more finely.

4. ViewConfiguration

If you want to further refine the control of events, such as setting the minimum click interval , long press timeout , etc., you can use ViewConfiguration to configure. Currently, the items that can be set are as follows:
insert image description here
It can be seen that the configuration of ViewConfiguration mainly affects combinedClickable and pointerInput.

LocalViewConfigurationThe global default ViewConfiguration can be obtained by . We can implement custom ViewConfiguration based on the default configuration by inheritance and rewriting. Then also realize the custom configuration of its internal local UI with the help of CompositionLocal.

The following example shows how to customize the long press timeout:

// 自定义 ViewConfiguration
class CustomViewConfiguration(
    private val defaultViewConfiguration: ViewConfiguration //传入默认配置
) : ViewConfiguration by defaultViewConfiguration {
    
    

    // 自定义长按超时3000ms
    override val longPressTimeoutMillis: Long = 3000
}

@Composable
fun Sample() {
    
    
    // 获取全局默认 ViewConfiguration
    val defaultViewConfiguration = LocalViewConfiguration.current

	// 基于默认配置创建自定义 CustomViewConfiguration
    val viewConfiguration = remember {
    
    
        CustomViewConfiguration(defaultViewConfiguration)
    }

    CompositionLocalProvider(
        LocalViewConfiguration provides viewConfiguration
    ) {
    
    
        // 内部的事件配置都受到 CustomViewConfiguration 影响
        Box(
            modifier = Modifier
                .combinedClickable(
                    onLongClick = {
    
    
                        // ...
                    },
                )
        )
    }
}

It is worth mentioning that it is ViewConfiguration.minimumTouchTargetSizeused to set the minimum size of the gesture responsive area. This is very practical and can solve the problem that some small-sized controls on the interface are more difficult to touch. So, by setting, it is possible that the area of ​​the Composable pointerInputthat can respond to events is larger than the area it actually renders. The offset value obtained at this time may be a negative number, or it may exceed the size of Compose.

The default value of minimumTouchTargetSize is 48.dp, so it is not surprising if we get a negative offset value during development.

class CustomViewConfiguration(
    private val defaultViewConfiguration: ViewConfiguration
) : ViewConfiguration by defaultViewConfiguration {
    
    

    override val minimumTouchTargetSize: DpSize = DpSize(0.dp, 0.dp)
}

As an experiment, if you set it to 0.dp, you will never get a negative offset. Of course, we do not recommend doing this, as it will cause difficult touches.

Guess you like

Origin blog.csdn.net/vitaviva/article/details/130037351