限制jetpack compose中文本字段中小数点前后的位数

RUG*_*ost 5 kotlin android-studio android-jetpack-compose

如何使 TextField 只接受整数作为输入,以及如何将小数点前的位数限制为 3,小数点后的位数限制为 2?

例如 NNN.NN,其中 N 是数字。

Arp*_*kla 10

第一步是设置keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number)TextField。当文本字段获得焦点时,这将打开数字键盘。

现在的问题是 TextField 本身不进行任何验证(与 EditText 不同inputType="number")。用户可以键入键盘上出现的任何字符(例如逗号、空格、破折号,甚至多个小数)。您需要自己完成所有这些验证。

试试这个代码:

var number by remember { mutableStateOf("") }
TextField(
    value = number,
    onValueChange = { number = getValidatedNumber(it) },
    keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number)
)
Run Code Online (Sandbox Code Playgroud)
fun getValidatedNumber(text: String): String {
    // Start by filtering out unwanted characters like commas and multiple decimals
    val filteredChars = text.filterIndexed { index, c ->
        c in "0123456789" ||                      // Take all digits
        (c == '.' && text.indexOf('.') == index)  // Take only the first decimal
    }
    // Now we need to remove extra digits from the input
    return if(filteredChars.contains('.')) {
        val beforeDecimal = filteredChars.substringBefore('.')
        val afterDecimal = filteredChars.substringAfter('.')
        beforeDecimal.take(3) + "." + afterDecimal.take(2)    // If decimal is present, take first 3 digits before decimal and first 2 digits after decimal
    } else {
        filteredChars.take(3)                     // If there is no decimal, just take the first 3 digits
    }
}
Run Code Online (Sandbox Code Playgroud)

我还没有测试过这段代码,但我认为它应该适用于大多数情况。它将确保最终输入不会超出原始约束,但可能会导致一些意外的行为。例如:

  • 如果当前文本是“123.45”并且用户将光标放在小数点后面并删除小数点。在这种情况下,新文本将变为“123”,即“45”将被删除,因为“12345”打破了“小数点前 3 位数字的限制”。
  • 如果当前文本是“123”并且用户将光标放在开头并输入“4”,则下一个文本将为“412”。“3”将被删除。

对于用户更改光标位置并键入内容的这些极端情况,您必须决定正确的行为应该是什么(就像在我的第一个示例中,您可能选择不允许删除小数并保留原始文本)。您必须getValidatedNumber根据您的具体要求在函数中添加此类条件。我有时在这里使用的一种解决方法是禁用光标位置更改,即光标将始​​终保留在末尾并且不能到达任意索引。