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

Compose Multiplatform(Wasm)如何精准识别鼠标点击、触摸及滚动拖拽事件?

Compose Multiplatform Wasm 指针事件精准处理方案

核心思路

利用Compose pointerInput中的PointerInputChange属性区分输入源、按钮类型,结合事件类型(Press/Release/Move/Scroll)实现精准的点击、拖拽、滚动处理。

代码实现

Column(
    modifier = Modifier.fillMaxWidth(),
    horizontalAlignment = Alignment.CenterHorizontally
) {
    Button(
        onClick = { /* 预留默认点击逻辑(可选) */ },
        modifier = Modifier
            .pointerInput(Unit) {
                awaitPointerEventScope {
                    var isDragging = false
                    while (true) {
                        val event = awaitPointerEvent()
                        val firstChange = event.changes.first()
                        val position = firstChange.position

                        when (event.type) {
                            // 按下事件:区分左键、右键、触控板轻击
                            PointerEventType.Press -> {
                                when (firstChange.button) {
                                    PointerButton.Primary -> {
                                        when (firstChange.source) {
                                            is PointerSource.Mouse -> list.add(0, "鼠标左键按下 $position")
                                            is PointerSource.Touch -> list.add(0, "触控板轻击按下 $position")
                                        }
                                    }
                                    PointerButton.Secondary -> {
                                        list.add(0, "鼠标右键按下 $position")
                                        firstChange.consume() // 阻止浏览器默认右键菜单
                                    }
                                }
                            }
                            // 释放事件:区分点击与拖拽
                            PointerEventType.Release -> {
                                when (firstChange.button) {
                                    PointerButton.Primary -> {
                                        if (!isDragging) {
                                            when (firstChange.source) {
                                                is PointerSource.Mouse -> {
                                                    list.add(0, "鼠标左键点击 $position")
                                                    // 执行左键点击业务逻辑
                                                    // navigator.push(Registration)
                                                }
                                                is PointerSource.Touch -> {
                                                    list.add(0, "触控板轻击完成 $position")
                                                }
                                            }
                                        }
                                    }
                                    PointerButton.Secondary -> list.add(0, "鼠标右键释放 $position")
                                }
                                isDragging = false
                            }
                            // 拖拽事件:标记拖拽状态并处理
                            PointerEventType.Move -> {
                                if (firstChange.pressed) {
                                    isDragging = true
                                    list.add(0, "拖拽中: $position")
                                    // 此处添加拖拽位置更新等逻辑
                                }
                            }
                            // 滚动事件:获取滚动偏移量
                            PointerEventType.Scroll -> {
                                val delta = event.scrollDelta
                                list.add(0, "滚动偏移: X=${delta.x}, Y=${delta.y}")
                                // 此处添加滚动相关业务逻辑
                            }
                        }
                        event.changes.forEach { it.consume() }
                    }
                }
            }
    ) {
        Text("Click me")
    }
}

关键细节说明

  • 按钮区分:通过PointerButton.Primary(左键/触控板轻击)、PointerButton.Secondary(右键)判断触发按钮
  • 输入源区分:PointerSource.Mouse对应物理鼠标,PointerSource.Touch对应触控板/触摸屏,用于区分左键点击和触控板轻击
  • 拖拽与点击区分:用isDragging标记,只有未触发拖拽的释放事件才判定为点击
  • 滚动处理:监听PointerEventType.Scroll,通过scrollDelta获取X/Y方向的滚动距离
  • 事件消费:调用consume()避免事件向下传递或触发浏览器默认行为(如右键菜单)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 12:57:08