Android Jetpack组合单个数字文本字段
我正在尝试创建一个电话验证屏幕,用户必须在自己的文本字段中分别输入5个号码,如下所示。 我有两个问题:Android Jetpack组合单个数字文本字段,android,textfield,android-jetpack,android-jetpack-compose,Android,Textfield,Android Jetpack,Android Jetpack Compose,我正在尝试创建一个电话验证屏幕,用户必须在自己的文本字段中分别输入5个号码,如下所示。 我有两个问题: 有没有办法将文本字段限制为1个字符。我可以设置单行和最大行数,但在视图系统中看不到限制字符长度的方法,如“Ms”。我可以通过忽略第一个字符之后的字符来轻松限制代码中的字符长度,但这仍然允许用户向左和向右“滚动”,即使只有一个字符 有没有办法将宽度换行到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))
}
}
}
@Composable
有趣的代码文本字段(
修饰符:修饰符=修饰符,
长度:Int=5,
onFilled:(代码:字符串)->单位
) {
var代码:按记忆列出{
mutableStateOf(listOf())
}
val focusRequesters:List=记住{
val temp=mutableListOf()
重复(长度){
临时添加(FocusRequester())
}
临时雇员
}
行(修饰符=修饰符){
(0到长度)。forEach{index->
大纲文本字段(
修饰语=修饰语
.重量(1f)
.填充(垂直=2.dp)
.focusRequester(focusRequesters[索引]),
textStyle=MaterialTheme.typography.h4.copy(textAlign=textAlign.Center),
单线=真,
value=code.getOrNull(index)?.takeIf{it.isDigit()}?.toString()?:“”,
onValueChange={value:String->
if(focusRequesters[index].freefoch()){//由于某种原因,这修复了focusrequestor导致on值更改为调用两次的问题
val temp=code.toMutableList()
如果(值==“”){
如果(温度大小>索引){
移除温度(索引)
代码=温度
focusRequesters.getOrNull(索引-1)?.requestFocus()
}
}否则{
如果(code.size>索引){
温度[索引]=值。getOrNull(0)?:“”
}else if(value.getOrNull(0)?.isDigit()==true){
临时添加(值getOrNull(0)?:“”)
代码=温度
focusRequesters.getOrNull(索引+1)?.requestFocus()?:已填充(
代码.joinToString(分隔符=“”)
)
}
}
}
},
keyboardOptions=keyboardOptions.Default.copy(
键盘类型=键盘类型。数字,
imeAction=imeAction.Next
),
)
间隔(修改器=修改器宽度(16.dp))
}
}
}
要限制为1个数字,您可以使用以下内容:
@Composable
fun Field (modifier: Modifier = Modifier,
onValueChange: (String, String) -> String = { _, new -> new }){
val state = rememberSaveable { mutableStateOf("") }
OutlinedTextField(
modifier = modifier.requiredWidth(75.dp),
singleLine = true,
value = state.value,
onValueChange = {
val value = onValueChange(state.value, it)
state.value = value
},
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Number,
imeAction = ImeAction.Next),
)
}
然后使用:
Field(onValueChange = { old, new ->
if (new.length > 1 || new.any { !it.isDigit() }) old else new
})