You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jetpack Compose:子组件长按事件向父组件自动传递的实现

解决Jetpack Compose父子组件点击/长按事件传递问题

问题分析

你当前的代码里,子组件用了默认的clickable修饰符——它会消费所有触摸事件(包括长按),所以长按子组件时,事件被子组件拦截,父组件的onLongClick根本收不到。要实现「子组件只处理常规点击,长按事件自动传递给父组件」的效果,完全不用给每个子组件手动加onLongClick,下面两种方案可以自动搞定:


方案1:自定义仅响应点击的修饰符

直接写一个替代默认clickable的修饰符,只处理点击,不拦截长按:

fun Modifier.onlyOnClick(onClick: () -> Unit): Modifier = composed {
    pointerInput(onClick) {
        detectTapGestures(
            onPress = { /* 空实现,不消费长按事件 */ },
            onTap = onClick
        )
    }
}

然后把所有子组件的clickable换成这个onlyOnClick就行:

Box(
    modifier = Modifier
        .fillMaxWidth()
        .combinedClickable(
            onLongClick = {
                Toast.makeText(context, "Long click parent", Toast.LENGTH_SHORT).show()
            },
            onClick = {
                Toast.makeText(context, "Normal click parent", Toast.LENGTH_SHORT).show()
            }
        )
        .padding(16.dp)
) {
    Box(
        modifier = Modifier
            .height(100.dp)
            .fillMaxWidth()
            .background(Color.Green)
            .onlyOnClick {
                Toast.makeText(context, "Normal click child", Toast.LENGTH_SHORT).show()
            }
    )
}

以后新增子组件,只要用这个自定义修饰符,就不会出现遗漏的问题。


方案2:直接用pointerInput处理点击

如果不想自定义修饰符,也可以直接在子组件里用pointerInput手动处理点击,不实现长按逻辑:

Box(
    modifier = Modifier
        .height(100.dp)
        .fillMaxWidth()
        .background(Color.Green)
        .pointerInput(Unit) {
            detectTapGestures(
                onTap = {
                    Toast.makeText(context, "Normal click child", Toast.LENGTH_SHORT).show()
                }
                // 不写onLongPress,长按事件会自动向上传给父组件
            )
        }
)

原理说明

默认的clickable内部调用了detectTapGestures,并且实现了onPress回调——这个回调会消费掉所有触摸事件,包括长按。我们通过空实现onPress或者不实现onLongPress,让长按事件不被拦截,自然就会传递到父组件的combinedClickable中。

内容的提问来源于stack exchange,提问作者Billda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 22:31:13