Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/227.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android Jetpack组合单个数字文本字段_Android_Textfield_Android Jetpack_Android Jetpack Compose - Fatal编程技术网

Android Jetpack组合单个数字文本字段

Android Jetpack组合单个数字文本字段,android,textfield,android-jetpack,android-jetpack-compose,Android,Textfield,Android Jetpack,Android Jetpack Compose,我正在尝试创建一个电话验证屏幕,用户必须在自己的文本字段中分别输入5个号码,如下所示。 我有两个问题: 有没有办法将文本字段限制为1个字符。我可以设置单行和最大行数,但在视图系统中看不到限制字符长度的方法,如“Ms”。我可以通过忽略第一个字符之后的字符来轻松限制代码中的字符长度,但这仍然允许用户向左和向右“滚动”,即使只有一个字符 有没有办法将宽度换行到1个字符?目前,我发现限制宽度的唯一方法是专门设置宽度,但如果系统文本大小更改,它可能会中断 以下是一些代码,以防有所帮助,这是一些非常混乱的

我正在尝试创建一个电话验证屏幕,用户必须在自己的文本字段中分别输入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
    })