我正在使用 Compose 开发一个桌面应用程序。 基本上我有一个文本编辑器,可以在其中打开不同的文本文件。问题是 TextField 在内部保留其撤消/重做状态(据我所知)。因此,当我打开文件 A,然后打开文件 B,然后按 Ctrl+Z,文件 B 内容会更改为文件 A。我想在打开新文件时清除撤消/重做状态,或者更好的是,保留每个文件的状态小路 (但这是我的要求的延伸)。
我不提供任何示例代码,它询问 Basic/TextField 组件的基本功能。
有什么想法吗?
另一种选择是使用一个列表进行
TextFieldValue
或 String
,并使用另一个列表进行重做。
结果
实施
class RedoState {
private val defaultValue = TextFieldValue()
private val textFieldValues = mutableListOf<TextFieldValue>()
private val undoneTextFieldValues = mutableListOf<TextFieldValue>()
var textFieldValue: TextFieldValue by mutableStateOf(defaultValue)
fun redoText() {
if (undoneTextFieldValues.isNotEmpty()) {
val lastItem = undoneTextFieldValues.last()
textFieldValue = undoneTextFieldValues.removeLast()
textFieldValues.add(lastItem)
}
}
fun undoText() {
if (textFieldValues.isNotEmpty()) {
val lastItem = textFieldValues.last()
textFieldValues.removeLast()
textFieldValues.lastOrNull()?.let {
textFieldValue = it
}?:run {
textFieldValue = defaultValue
}
undoneTextFieldValues.add(lastItem)
}
}
fun update(newValue: TextFieldValue) {
if (textFieldValues.isEmpty() || (textFieldValue.text != newValue.text)
) {
textFieldValues.add(newValue)
}
textFieldValue = newValue
}
}
更新或从中获取值的 TextField。
@Composable
fun EditableTextField(
redoState: RedoState = remember {
RedoState()
}
) {
val textFieldValue = redoState.textFieldValue
TextField(
value = textFieldValue,
onValueChange = {
redoState.update(it)
}
)
}
使用方法
@Preview
@Composable
fun UndoRedoTest() {
Column(
modifier = Modifier.fillMaxSize().padding(32.dp)
) {
val redoState = remember {
RedoState()
}
EditableTextField(redoState)
Row {
Button(
modifier = Modifier.weight(1f),
onClick = {
redoState.undoText()
}
) {
Text("Undo")
}
Spacer(Modifier.width(16.dp))
Button(
modifier = Modifier.weight(1f),
onClick = {
redoState.redoText()
}
) {
Text("Redo")
}
}
}
}