Compose编辑TextField时如何处理按键事件?
How to handle key events during TextField editing in Compose?
我正在桌面 compose 上制作国际象棋引擎,我正在尝试实现的其中一件事是 TextField
我可以在其中粘贴几个动作来重新创建游戏。
我在将输入的文本保存到 TextField
可组合项时遇到问题。
我的文本可组合如下,我知道在我当前的实现中,每次移动变量更改时它都会打印,但我只是希望在我按下 ENTER 时发生这种情况我键盘上的键。
我正在使用 print 来尝试一些代码,但我想做的是将字符串保存到列表或其他内容中,但我稍后可以自己实现。
我只找到关于如何使用 android 和 android 特定方法的解释。
Text(" Play", textAlign = TextAlign.Center, fontSize = 30.sp)
val move = remember { mutableStateOf("Play") }
TextField(
value = move.value,
onValueChange = { move.value = it },
label = { Text("Move") },
maxLines = 1,
textStyle = TextStyle(color = Color.Black, fontWeight = FontWeight.Bold),
modifier = Modifier.padding(20.dp)
)
println(move.value)
有人向我指出了一个处理 ENTER 键绑定的解决方案,如下所述:
我只是遇到了一些问题,当我按下 ENTER 时无法处理字符串,它会连续打印一次,而不是只打印一次基于我的研究我需要实施这样的事情:
但我似乎无法使用 KeyEvent.ACTION_UP
不确定它是否特定于 editText,是否缺少一些导入,或者是否有另一种方法可以使用 TextField 可组合项。
根据给出的建议我的代码
val requester = remember { FocusRequester() }
LaunchedEffect(Unit) {
requester.requestFocus()
}
Text(" Play", textAlign = TextAlign.Center, fontSize = 30.sp)
val move = remember { mutableStateOf("Play") }
TextField(
value = move.value,
onValueChange = { move.value = it },
label = { Text("Move") },
maxLines = 1,
textStyle = TextStyle(color = Color.Black, fontWeight = FontWeight.Bold),
modifier = Modifier.padding(20.dp)
.onKeyEvent {
//if(keyCode==KeyEvent.KEYCODE_ENTER&&event.action==KeyEvent.ACTION_UP){
if (it.key == Key.Enter) {
println(move.value)
true
} else {
// let other handlers receive this event
false
}
}
.focusRequester(requester)
.focusable()
)
我设法通过将 if 条件更改为此来解决此问题:
if (it.key == Key.Enter && move.value!="") {
println(move.value)
move.value = ""
true
}
所以每次我写东西然后按 ENTER 它打印字符串并清除 mutableState,而 ENTER 仍然按下它不会打印,因为 mutableState 是空字符串。
我仍在寻找比这更好的解决方案
您可以使用 Modifier.onKeyEvent
捕获关键事件。使用文本字段,您不需要任何焦点捕获,因为它已经存在。如果您需要对自定义视图执行相同的操作,请查看
要检查哪个按钮被按下,您可以使用 key
,要检查按钮被释放的位置,您可以检查 type
:
TextField(
value = text,
onValueChange = { text = it },
modifier = Modifier
.onKeyEvent { keyEvent ->
if (keyEvent.key != Key.Enter) return@onKeyEvent false
if (keyEvent.type == KeyEventType.KeyUp) {
println("Enter released")
}
true
}
)
我正在桌面 compose 上制作国际象棋引擎,我正在尝试实现的其中一件事是 TextField
我可以在其中粘贴几个动作来重新创建游戏。
我在将输入的文本保存到 TextField
可组合项时遇到问题。
我的文本可组合如下,我知道在我当前的实现中,每次移动变量更改时它都会打印,但我只是希望在我按下 ENTER 时发生这种情况我键盘上的键。
我正在使用 print 来尝试一些代码,但我想做的是将字符串保存到列表或其他内容中,但我稍后可以自己实现。
我只找到关于如何使用 android 和 android 特定方法的解释。
Text(" Play", textAlign = TextAlign.Center, fontSize = 30.sp)
val move = remember { mutableStateOf("Play") }
TextField(
value = move.value,
onValueChange = { move.value = it },
label = { Text("Move") },
maxLines = 1,
textStyle = TextStyle(color = Color.Black, fontWeight = FontWeight.Bold),
modifier = Modifier.padding(20.dp)
)
println(move.value)
有人向我指出了一个处理 ENTER 键绑定的解决方案,如下所述:
KeyEvent.ACTION_UP
不确定它是否特定于 editText,是否缺少一些导入,或者是否有另一种方法可以使用 TextField 可组合项。
根据给出的建议我的代码
val requester = remember { FocusRequester() }
LaunchedEffect(Unit) {
requester.requestFocus()
}
Text(" Play", textAlign = TextAlign.Center, fontSize = 30.sp)
val move = remember { mutableStateOf("Play") }
TextField(
value = move.value,
onValueChange = { move.value = it },
label = { Text("Move") },
maxLines = 1,
textStyle = TextStyle(color = Color.Black, fontWeight = FontWeight.Bold),
modifier = Modifier.padding(20.dp)
.onKeyEvent {
//if(keyCode==KeyEvent.KEYCODE_ENTER&&event.action==KeyEvent.ACTION_UP){
if (it.key == Key.Enter) {
println(move.value)
true
} else {
// let other handlers receive this event
false
}
}
.focusRequester(requester)
.focusable()
)
我设法通过将 if 条件更改为此来解决此问题:
if (it.key == Key.Enter && move.value!="") {
println(move.value)
move.value = ""
true
}
所以每次我写东西然后按 ENTER 它打印字符串并清除 mutableState,而 ENTER 仍然按下它不会打印,因为 mutableState 是空字符串。 我仍在寻找比这更好的解决方案
您可以使用 Modifier.onKeyEvent
捕获关键事件。使用文本字段,您不需要任何焦点捕获,因为它已经存在。如果您需要对自定义视图执行相同的操作,请查看
要检查哪个按钮被按下,您可以使用 key
,要检查按钮被释放的位置,您可以检查 type
:
TextField(
value = text,
onValueChange = { text = it },
modifier = Modifier
.onKeyEvent { keyEvent ->
if (keyEvent.key != Key.Enter) return@onKeyEvent false
if (keyEvent.type == KeyEventType.KeyUp) {
println("Enter released")
}
true
}
)