【问题标题】:Jetpack compose single number text fieldJetpack 组合单个数字文本字段
【发布时间】:2021-04-09 17:23:26
【问题描述】:

我正在尝试创建一个电话验证屏幕,用户必须在其自己的文本字段中分别输入 5 个数字,如下所示。

我有两个问题:

  1. 有没有办法将 TextField 限制为 1 个字符。我可以设置单行和最大行数,但从视图系统中看不到限制字符长度的方法,例如“Ms”。我可以通过忽略第一个字符之后的字符来轻松限制代码中的字符长度,但这仍然允许用户向左和向右“滚动”,即使只有 1 个字符。
  2. 有没有办法将宽度换行到 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


    【解决方案1】:

    要限制为 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
    })
    

    【讨论】:

      【解决方案2】:

      设置您的键盘选项编号密码类型见下面的代码

      keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.NumberPassword)
      

      在键盘输出下方

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-04-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-04
        • 1970-01-01
        • 2022-06-27
        相关资源
        最近更新 更多