[英]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 = { }
只有沒有start和count的字符串返回。
我搜索並沒有找到任何東西。
如何在 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.