簡體   English   中英

如何處理 Jetpack Compose 的 TextField 中的 doOnTextChanged 和 doBeforeTextChanged?

[英]How to handle doOnTextChanged and doBeforeTextChanged in TextField of Jetpack Compose?

我需要在 Jetpack Compose 中為 TextField 實現重做/撤消。 對於 EditText,我使用了這個並且效果很好。 但是,對於 Jetpack Compose,沒有這樣的監聽器。 我會在 EditText 的基礎上實現一個自己的方法,但是我缺少這兩個偵聽器方法,它們不適用於 TextField:

doOnTextChanged { text, start, before, count -> }
doBeforeTextChanged { text, start, count, after -> }

在 TextField 中僅使用一個偵聽器

onValuesChange = { }

只有沒有startcount字符串返回。

我搜索並沒有找到任何東西。

如何在 Jetpack Compose 中實現重做/撤消以實現 TextField?

謝謝。

編輯:

順便說一句,這就是我到目前為止所做的。 讓它可以運行會很棒。

class EditTextDo {

    private var mIsUndoOrRedo = false
    private val editHistory: EditHistory? = null

    fun redo() {
        val edit = editHistory?.getNext() ?: return

        // Do Redo
    }

    fun undo() {
        val edit = editHistory?.getPrevious() ?: return

        // Do Undo
    }

    fun canUndo(): Boolean {
        editHistory?.let {
            return it.position > 0
        }
        return false
    }

    fun canRedo(): Boolean {
        editHistory?.let {
            return it.position < it.history.size
        }
        return false
    }

}

class EditHistory {

    var position = 0

    private var maxHistorySize = -1

    val history = LinkedList<EditItem>()

    private fun clear() {
        position = 0
        history.clear()
    }

    fun add(item: EditItem) {
        while (history.size > position) {
            history.removeLast()
        }
        history.add(item)
        position++
        if (maxHistorySize >= 0)
            trimHistory()
    }

    fun getNext(): EditItem? {
        if (position >= history.size) {
            return null
        }
        val item = history[position]
        position++
        return item
    }

    fun getPrevious(): EditItem? {
        if (position == 0) {
            return null
        }
        position--
        return history[position]
    }

    private fun setMaxHistorySize(maxHistorySize: Int) {
        this.maxHistorySize = maxHistorySize
        if (maxHistorySize >= 0)
            trimHistory()
    }

    private fun trimHistory() {
        while (history.size > maxHistorySize) {
            history.removeFirst()
            position--
        }
        if (position < 0)
            position = 0
    }
}

data class EditItem(val start: Int, val before: CharSequence, val after: CharSequence)

這可能無法完全解決您的帖子,但希望對您有所幫助。 我的項目中有一個簡單的undo/redo Textfield ,使用Queue結構來跟蹤輸入歷史記錄,但我沒有指定歷史記錄大小。

可組合的

@Composable
fun TextFieldWithHistory() {

val undoRedoState = remember { UndoRedoState() }

Column(
    modifier = Modifier
        .fillMaxWidth()
        .wrapContentHeight()
) {
    TextField(
        value = undoRedoState.input,
        onValueChange = {
            undoRedoState.onInput(it)
        }
    )

    Button(
        onClick = {
            undoRedoState.undo()
        }) {
        Text(text = "Undo")
    }


    Button(
        onClick = {
            undoRedoState.redo()
        }) {
        Text(text = "Redo")
    }
}

State

class UndoRedoState {

var input by mutableStateOf("")
var undoHistory = ArrayDeque<String?>()
var redoHistory = ArrayDeque<String?>()

init {
    undoHistory.add(input)
}

fun onInput(value: String) {
    undoHistory.add(value)
    input = value
}

fun undo() {

    if (undoHistory.size > 1) {

        // pop the last
        val pop = undoHistory.removeLastOrNull()
        if (pop.isNotNullOrEmpty() && pop.isNotBlank()) {
            redoHistory.add(pop)
        }

        // peek the last
        val peek = undoHistory.lastOrNull()
        peek?.let{
            input = it
        }
    }
}

fun redo() {
    val pop = redoHistory.removeLastOrNull()
    if (pop.isNotNullOrEmpty()) {
        undoHistory.add(pop)
        input = pop
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM