kotlin 文本字段最大长度-Android Jetpack编写

kxe2p93d  于 2022-11-30  发布在  Kotlin
关注(0)|答案(5)|浏览(256)

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

vojdkbi0

vojdkbi01#

对于1.x.y,没有内置的参数。

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

TextField(
    singleLine = true,
    value = text,
    onValueChange = {
        if (it.length <= maxChar) text = it         
    }
)

要显示计数器文本,您可以使用类似如下的内容:

val maxChar = 5

Column(){
    TextField(
        value = text,
        onValueChange = {
            if (it.length <= maxChar) text = it
        },
        singleLine = true,
        modifier = Modifier.fillMaxWidth()
    )
    Text(
        text = "${text.length} / $maxChar",
        textAlign = TextAlign.End,
        style = MaterialTheme.typography.caption,
        modifier = Modifier.fillMaxWidth().padding(end = 16.dp)
    )
}

zmeyuzjn

zmeyuzjn2#

这个问题的第一个答案很好用,但在某些情况下,当超过允许的字符数时,文本域的值会被清除。这个错误似乎是由于预测文本造成的,因为如果在android中禁用预测文本,它就不会发生。我现在找到的一个解决方案是使用focusManager来"限制写入"。
首先,我们需要让焦点管理器控制屏幕上的焦点。我们可以通过在可组合函数中添加以下行来实现:

val focusManager = LocalFocusManager.current

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

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

TextField(
    singleLine = true,
    value = text,
    onValueChange = {
        // This line will take (in case the user try to paste a text from the clipboard) only the allowed amount of characters
        text = it.take(maxChar)
        if (it.length > maxChar){
           focusManager.moveFocus(FocusDirection.Down) // Or receive a lambda function
        }
    }
)

通过这种方式,用户永远不会写更多的字符超过所建立的限制。显然,这是一个替代的解决方案,在我的情况下解决了我的问题,现在我们必须等待,看看他们是否添加它本身

umuewwlo

umuewwlo3#

如果新字符串超过长度,则根据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
    }
}

用法:

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

PaddingTextField(
    value = phone,
    onValueChange = { newPhone ->
        setPhone(newPhone.ofMaxLength(11))
    }
)
eeq64g8w

eeq64g8w4#

您可以使用take函数-here documentation
值变化= {年变化(值(限制数))})
例如,如果您将在函数中使用它。

fun YearRow(year: Int, onYearChanged: (String) -> Unit)
{
    val limitNum = 4
    OutlinedTextField(
        value = if(year==0) "" else "$year",
        onValueChange = { onYearChanged(it.take(limitNum)) })
}
hlswsv35

hlswsv355#

另一种更灵活的方法是:

Text(
    text = "A string with a lot of charsssssssssssssssssssssssssss"
    modifier = Modifier.fillMaxWidth(.5f),
    maxLines = 1,
    overflow = TextOverflow.Ellipsis
)

这将限制fillMaxWidth位的宽度和maxLines部分的高度。如果同时满足这两个限制,文本将溢出,可以指定溢出的行为
在这种情况下,一旦文本占据了视图的一半或超过一行,它将以类似A string with a lot of charsssss...的形式结束,

相关问题