我有一个可组合函数,可显示 2 个
TextField
。这是我的代码:
fun CreateEntryItem() {
var wordA by remember { mutableStateOf("") }
var wordB by remember { mutableStateOf("") }
Column {
Row {
TextField(
value = wordA,
onValueChange = { wordA = it },
enabled = true,
modifier = Modifier.weight(1f)
)
TextField(
value = wordB,
onValueChange = { wordB = it },
enabled = true,
modifier = Modifier.weight(1f)
)
}
}
}
当我将焦点置于文本字段 A 时,我可以键入内容,并且
wordA
的值会正确更新。
这是奇怪的行为:
然后我将焦点赋予 TextField B。然后将焦点重新赋予 TextField A。当我开始键入时,TextField A 不是在现有文本中的光标位置插入/附加字符,而是完全清除现有文本(如预先设置的那样) -焦点)和“重新开始”。也就是说,每个 TextField 只记住当前“焦点会话”中输入的文本。
我这样做错了吗?或者这是 Compose 中的一个错误?我在
1.0.0-beta07
和 1.0.0-beta08
上重现了这种行为。
事实证明,这本身并不是 Compose 错误,而是模拟器问题。在真实设备上运行完全相同的代码不会遇到此问题。
遇到此问题的模拟器是在 macOS Big Sur 上运行的 API 30。我还没有测试过其他系统是否也受到这个模拟器bug的影响。
我也有同样的问题。我的问题出现在运行 Android 27 的自定义 Android 设备上。
我能够将问题追溯到
IInputConnectionWrapper.executeMessage()
当我第一次开始输入字符时,我收到
message.what = DO_SET_COMPOSING_TEXT
。
重新获得焦点后,第一条关于新角色的消息是
message.what = DO_COMMIT_TEXT
。我不知道为什么消息类型改变了。
如果您进一步查看调用堆栈到
RecordingInputConnection
,您会发现 DO_COMMIT_TEXT
会触发 CommitTextCommand
,其设计会清除所有文本:
// API description says replace ongoing composition text if there. Then, if there is no
// composition text, insert text into cursor position or replace selection.
if (buffer.hasComposition()) {
buffer.replace(buffer.compositionStart, buffer.compositionEnd, text)
} else {
// In this editing buffer, insert into cursor or replace selection are equivalent.
buffer.replace(buffer.selectionStart, buffer.selectionEnd, text)
}
由于我无法在此设备上调试 IME,因此我将 Compose
TextField
替换为 AndroidView
包装 android.view.TextView
。这不是一个很好的解决方案,但它有效。