在TextFieldJetpack Compose 中進行探索時,我遇到了一個案例,我必須修改在該欄位中鍵入的輸入。例如,輸入 3 個字符后添加逗號。
我就是這樣制作的。
@Composable
fun TFDemo() {
var fieldValue by remember { mutableStateOf(TextFieldValue("")) }
TextField(
value = fieldValue,
onValueChange = {
val newMessage = it.text.let { text -> if (text.length == 3) "$text," else text }
fieldValue = it.copy(newMessage, selection = TextRange(newMessage.length))
},
keyboardOptions = KeyboardOptions(autoCorrect = false),
)
}
但是在運行它之后,我意識到在添加逗號后,鍵盤視圖從數字/符號變回字母,這不應該是這種情況。為清楚起見,請參閱下面的視頻輸出
正如您在下面的視頻中看到的那樣,當我輸入“111”逗號時,突然鍵盤的數字視圖再次更改為字母。

在這里,我修改了selectionof,TextFieldValue以便在附加逗號時游標始終位于訊息的末尾。
uj5u.com熱心網友回復:
這種情況正是我們VisualTransformation想要的。
這是谷歌員工對另一個問題的評論:
我認為我們不能輕易解決這個問題。
通常不推薦在 onValueChanged 回呼中過濾文本,因為文本狀態與行程 IME(軟鍵盤)共享。過濾文本是指文本內容在內部發生變化,然后將新狀態通知給 IME。這不是 IME 的正常路徑,不同的 IME 對這種意外的狀態變化有不同的反應。一些 IME 可能會嘗試重建組成,其他人可能會放棄并開始新的會話等。這主要是由于歷史原因,現在很難修復。因此,請避免在 onValueChanged 回呼中過濾文本并考慮以下替代方案:
- (推薦)不要過濾它并顯示錯誤訊息。(此處無關)
- 使用 VisualTransformation 在不修改編輯緩沖區的情況下更改視覺輸出。
uj5u.com熱心網友回復:
根據上面提到的答案,VisualTransformation是這種情況的完美解決方案,我們不應該直接修改 TextField 的緩沖區。因為VisualTransformation只是改變了文本的視覺輸出,而不是實際的文本。
我在這里寫了一篇關于這種情況的文章,我已經詳細解釋了這一點。
解決方案:
@Composable
fun TextFieldDemo() {
var message by remember { mutableStateOf("") }
TextField(
value = message,
placeholder = { Text("Enter amount or message") },
onValueChange = { message = it },
visualTransformation = AmountOrMessageVisualTransformation()
)
}
class AmountOrMessageVisualTransformation : VisualTransformation {
override fun filter(text: AnnotatedString): TransformedText {
val originalText = text.text
val formattedText = formatAmountOrMessage(text.text)
val offsetMapping = object : OffsetMapping {
override fun originalToTransformed(offset: Int): Int {
if (originalText.isValidFormattableAmount) {
val commas = formattedText.count { it == ',' }
return when {
offset <= 1 -> offset
offset <= 3 -> if (commas >= 1) offset 1 else offset
offset <= 5 -> if (commas == 2) offset 2 else offset 1
else -> 8
}
}
return offset
}
override fun transformedToOriginal(offset: Int): Int {
if (originalText.isValidFormattableAmount) {
val commas = formattedText.count { it == ',' }
return when (offset) {
8, 7 -> offset - 2
6 -> if (commas == 1) 5 else 4
5 -> if (commas == 1) 4 else if (commas == 2) 3 else offset
4, 3 -> if (commas >= 1) offset - 1 else offset
2 -> if (commas == 2) 1 else offset
else -> offset
}
}
return offset
}
}
return TransformedText(
text = AnnotatedString(formattedText),
offsetMapping = offsetMapping
)
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/403858.html
標籤:
