【发布时间】:2021-04-09 17:23:26
【问题描述】:
我正在尝试创建一个电话验证屏幕,用户必须在其自己的文本字段中分别输入 5 个数字,如下所示。
我有两个问题:
- 有没有办法将 TextField 限制为 1 个字符。我可以设置单行和最大行数,但从视图系统中看不到限制字符长度的方法,例如“Ms”。我可以通过忽略第一个字符之后的字符来轻松限制代码中的字符长度,但这仍然允许用户向左和向右“滚动”,即使只有 1 个字符。
- 有没有办法将宽度换行到 1 个字符?目前我发现限制宽度的唯一方法是专门设置它,但是如果系统文本大小发生更改,它可能会中断。
这是一些有用的代码,这是一些非常混乱的解决方案,如果有什么不正确的地方,请道歉:
@Composable
fun CodeTextFields(
modifier: Modifier = Modifier,
length: Int = 5,
onFilled: (code: String) -> Unit
) {
var code: List<Char> by remember {
mutableStateOf(listOf())
}
val focusRequesters: List<FocusRequester> = remember {
val temp = mutableListOf<FocusRequester>()
repeat(length) {
temp.add(FocusRequester())
}
temp
}
Row(modifier = modifier) {
(0 until length).forEach { index ->
OutlinedTextField(
modifier = Modifier
.weight(1f)
.padding(vertical = 2.dp)
.focusRequester(focusRequesters[index]),
textStyle = MaterialTheme.typography.h4.copy(textAlign = TextAlign.Center),
singleLine = true,
value = code.getOrNull(index)?.takeIf { it.isDigit() }?.toString() ?: "",
onValueChange = { value: String ->
if (focusRequesters[index].freeFocus()) { //For some reason this fixes the issue of focusrequestor causing on value changed to call twice
val temp = code.toMutableList()
if (value == "") {
if (temp.size > index) {
temp.removeAt(index)
code = temp
focusRequesters.getOrNull(index - 1)?.requestFocus()
}
} else {
if (code.size > index) {
temp[index] = value.getOrNull(0) ?: ' '
} else if (value.getOrNull(0)?.isDigit() == true) {
temp.add(value.getOrNull(0) ?: ' ')
code = temp
focusRequesters.getOrNull(index + 1)?.requestFocus() ?: onFilled(
code.joinToString(separator = "")
)
}
}
}
},
keyboardOptions = KeyboardOptions.Default.copy(
keyboardType = KeyboardType.Number,
imeAction = ImeAction.Next
),
)
Spacer(modifier = Modifier.width(16.dp))
}
}
}
【问题讨论】:
标签: android textfield android-jetpack android-jetpack-compose