TextField maxLength - Android Jetpack Compose

Has*_*ssa 6 android kotlin android-jetpack-compose

是否有任何开箱即用的解决方案来限制 TextField 中的字符大小?我没有看到像 XML 中那样的任何 maxLength 参数。

Gab*_*tti 13

1.0.x没有内置的参数。您可以使用以下内容:

var text by remember { mutableStateOf(TextFieldValue("")) }
val maxChar = 5

TextField(
    singleLine = true,
    value = text,
    onValueChange = {
        if (it.length <= maxChar) text = it         
    }
)
Run Code Online (Sandbox Code Playgroud)

  • 粘贴长文本可以实现吗?`text = it.take(maxChar)` 不是更好吗? (8认同)
  • 使用代码片段时,如果输入 `maxChar` 字符,它就可以正常工作。然后,对于下一个字符,它不会显示任何新字符(正确的行为),但是当输入另一个字符(“maxChar = 5”的第 7 个字符)时,它会清除“TextField”并允许新的字符输入。有什么解释为什么它会这样并且可能有解决办法吗? (5认同)

小智 10

您可以使用 take 函数 -这里文档

onValueChange = { onYearChanged(it.take(limitNum)) })
Run Code Online (Sandbox Code Playgroud)

例如,如果您将在函数中使用它。

const val limitNum = 4

@Composable
fun YearRow(
  modifier: Modifier = Modifier,
  year: Int, 
  onYearChanged: (String) -> Unit,
) {
  OutlinedTextField(
    modifier = modifier,
    value = if (year == 0) "" else "$year",
    onValueChange = { onYearChanged(it.take(limitNum)) },
  )
}
Run Code Online (Sandbox Code Playgroud)


Ern*_*reu 7

这个问题的第一个答案工作正常,但是\xc2\xb4s确实在某些情况下存在错误,当超过允许的字符数时,文本字段的值被清除。这种失败似乎是由于预测文本造成的,因为如果在 android 中禁用预测文本,则不会发生这种情况。我现在找到的一个解决方案是使用 focusManager 来“限制写入”。

\n

首先,我们需要让焦点管理器控制屏幕上的焦点。\n我们可以通过在可组合函数中添加这一行来做到这一点:

\n
val focusManager = LocalFocusManager.current\n
Run Code Online (Sandbox Code Playgroud)\n

然后,在我们的 TextField 中,我们可以使用 focusManager 来避免用户写入超过 maxChar 限制。我们可以将焦点移动到下一个元素,在超过 maxChar 限制时清除焦点,或者接收 lambda 函数并执行我们想要的操作。这取决于我们。

\n
var text by remember { mutableStateOf(TextFieldValue("")) }\nval maxChar = 10\n\nTextField(\n    singleLine = true,\n    value = text,\n    onValueChange = {\n        // This line will take (in case the user try to paste a text from the clipboard) only the allowed amount of characters\n        text = it.take(maxChar)\n        if (it.length > maxChar){\n           focusManager.moveFocus(FocusDirection.Down) // Or receive a lambda function\n        }\n    }\n)\n
Run Code Online (Sandbox Code Playgroud)\n

这样,用户写入的字符永远不会超过限制所规定的字符数。显然,这是一个替代解决方案,就我而言,它解决了我的问题,现在我们必须等待,看看他们是否本地添加它

\n


小智 6

selection如果新字符串超过长度,则根据 修剪最近插入的字符。

fun TextFieldValue.ofMaxLength(maxLength: Int): TextFieldValue {
    val overLength = text.length - maxLength
    return if (overLength > 0) {
        val headIndex = selection.end - overLength
        val trailIndex = selection.end
        // Under normal conditions, headIndex >= 0
        if (headIndex >= 0) {
            copy(
                text = text.substring(0, headIndex) + text.substring(trailIndex, text.length),
                selection = TextRange(headIndex)
            )
        } else {
            // exceptional
            copy(text.take(maxLength), selection = TextRange(maxLength))
        }
    } else {
        this
    }
}
Run Code Online (Sandbox Code Playgroud)

用法:

val (phone, setPhone) = remember {
    mutableStateOf(TextFieldValue())
}

PaddingTextField(
    value = phone,
    onValueChange = { newPhone ->
        setPhone(newPhone.ofMaxLength(11))
    }
)
Run Code Online (Sandbox Code Playgroud)