Kotlin/Wasm键盘事件实现求助:无法通过方向键移动方块
Kotlin/Wasm Compose 键盘事件实现思路
问题分析
你当前的代码在Kotlin/Wasm环境下无法响应方向键,核心原因有两个:
- 焦点缺失:Web端Compose组件默认不会自动获取焦点,无焦点的元素无法捕获键盘事件。
- 单位不匹配:Canvas绘制使用像素(px)单位,你直接修改的
xPosition是无单位浮点数,和布局的dp单位脱节,即使事件触发也可能看不到明显移动效果。
解决方案
1. 给容器添加焦点支持
为接收键盘事件的Column添加focusable()修饰符,并通过FocusRequester主动请求焦点,确保组件能捕获键盘事件。
2. 统一坐标单位
使用LocalDensity将dp转换为像素,保证Canvas绘制的位置和布局单位一致,移动效果符合预期。
修改后的完整代码
@Composable @Preview fun mainScreen() { var xPosition by remember { mutableStateOf(0f) } val density = LocalDensity.current val focusRequester = remember { FocusRequester() } Column( modifier = Modifier .fillMaxSize() .background(color = Color.Red) .focusRequester(focusRequester) .focusable() .onPreviewKeyEvent { event: KeyEvent -> if (event.type == KeyEventType.KeyDown || event.type == KeyEventType.KeyRepeat) { val moveStep = with(density) { 10.dp.toPx() } when (event.key) { Key.DirectionLeft -> { xPosition -= moveStep true } Key.DirectionRight -> { xPosition += moveStep true } else -> false } } else false }, verticalArrangement = Arrangement.Center ) { Box( modifier = Modifier .size(100.dp) ) { Canvas(modifier = Modifier.fillMaxSize()) { drawRect( color = Color.Blue, topLeft = Offset(xPosition, 0f), size = Size(with(density) { 100.dp.toPx() }, with(density) { 100.dp.toPx() }) ) } } } LaunchedEffect(Unit) { focusRequester.requestFocus() } }
额外说明
- 若
Key.DirectionLeft/DirectionRight在Wasm环境下不生效,可尝试直接匹配键名:event.key.name == "ArrowLeft"。 - 代码中加入了
KeyEventType.KeyRepeat的判断,支持按住方向键时连续移动方块。
内容的提问来源于stack exchange,提问作者olracnai
相关产品推荐
相关产品推荐

