如何清除 Jetpack Compose TextField(或 BasicTextField)中的撤消/重做历史记录

问题描述 投票:0回答:1

我正在使用 Compose 开发一个桌面应用程序。 基本上我有一个文本编辑器,可以在其中打开不同的文本文件。问题是 TextField 在内部保留其撤消/重做状态(据我所知)。因此,当我打开文件 A,然后打开文件 B,然后按 Ctrl+Z,文件 B 内容会更改为文件 A。我想在打开新文件时清除撤消/重做状态,或者更好的是,保留每个文件的状态小路 (但这是我的要求的延伸)。

我不提供任何示例代码,它询问 Basic/TextField 组件的基本功能。

有什么想法吗?

kotlin android-jetpack-compose textfield undo-redo compose-desktop
1个回答
0
投票

另一种选择是使用一个列表进行

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")
            }
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.