是否有现成的解决方案来限制TextField文本框的字符大小?我没有看到像XML中的maxLength参数。
是否有现成的解决方案来限制TextField文本框的字符大小?我没有看到像XML中的maxLength参数。
你可以使用 onValueChange
参数来限制字符数。
var text by remember { mutableStateOf("") }
val maxChar = 5
TextField(
value = text,
onValueChange = {
if (it.length <= maxChar) text = it
}
singleLine = true,
)
然后使用M3,您可以使用supportingText
属性来显示counter text
。
类似这样:
val maxChar = 5
TextField(
value = text,
onValueChange = {
if (it.length <= maxChar) text = it
},
modifier = Modifier.fillMaxWidth(),
supportingText = {
Text(
text = "${text.length} / $maxChar",
modifier = Modifier.fillMaxWidth(),
textAlign = TextAlign.End,
)
},
)
使用 M2 时,没有内置参数。
在这种情况下,您可以使用类似以下的方式来显示计数器文本:
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)
)
}
onValueChange = { onYearChanged(it.take(limitNum)) })
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)) },
)
}
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
}
}
)
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))
}
)
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...
的形式结束。
maxChar
个字符,则可以正常工作。然后,下一个字符将不会显示任何新字符(正确行为),但是当输入另一个字符(对于maxChar = 5
的第7个字符)时,它会清除TextField
并允许重新输入字符。请问这种行为的原因是什么,是否有可能修复? - adek111text = it.take(maxChar)
不是更好吗? - John Doe