Jetpack 撰写键盘操作侦听器 (setOnKeyListener)(短信文本字段)

Bor*_*kov 6 android event-listener textfield kotlin android-jetpack-compose

我有五个文本字段。在第一个字段中输入内容后,焦点将移动到下一个文本字段。如果我删除了文本字段中的某些内容 - 焦点会移动到上一个文本字段。所有具有焦点的工作都经过 onValueChanged 部分

但是,如果文本字段中的值为空白(“”) - 如果我在键盘中按退格键,则 onValueChanged 不会发生任何情况,因为字段中的值未更改。我需要以某种方式将焦点集中在前一个文本字段上

在此输入图像描述

那么我如何在撰写文本字段的软键盘中使用侦听器进行后按?

我尝试使用 KeyboardActions,

keyboardActions = KeyboardActions(
                    onPrevious = {
                        //some work with foucs
                    },
                ),
Run Code Online (Sandbox Code Playgroud)

但它不起作用

第二个问题:如果文本字段被单击(或获得焦点),如何在结束文本的字段中设置光标?
即使用户单击字符串光标中间的设置,我也需要。

Bor*_*kov 1

使用解决方案@nglauber Textfield 输入短信(目前):

@Composable
fun SMSTextFields(
    modifier: Modifier,
    smsCodeLength: Int = 5,
    whenFull: (smsCode: String) -> Unit
) {
    val enteredNumbers = remember {
        mutableStateListOf(
            *((0 until smsCodeLength).map { "" }.toTypedArray())
        )
    }
    val focusRequesters: List<FocusRequester> = remember {
        (0 until smsCodeLength).map { FocusRequester() }
    }
    Row(modifier = modifier.padding(start = 60.dp, end = 60.dp)) {
        (0 until smsCodeLength).forEach { index ->
            TextField(
                modifier = Modifier
                    .weight(1f)
                    .size(120.dp, 80.dp)
                    .onKeyEvent { event ->
                        val cellValue = enteredNumbers[index]
                        if (event.type == KeyEventType.KeyUp) {
                            if (event.key == Key.Backspace && cellValue == "") {
                                focusRequesters
                                    .getOrNull(index - 1)
                                    ?.requestFocus()
                                enteredNumbers[index - 1] = ""
                            } else if (cellValue != "") {
                                focusRequesters
                                    .getOrNull(index + 1)
                                    ?.requestFocus()
                            }
                        }
                        false
                    }
                    .padding(vertical = 2.dp)
                    .focusOrder(focusRequesters[index])
                    .focusRequester(focusRequesters[index]),
                colors = TextFieldDefaults.textFieldColors(
                    backgroundColor = whiteBackground,
                    unfocusedIndicatorColor = greyColor,
                    focusedIndicatorColor = signUpColorButton,
                    cursorColor = greyColor,
                    textColor = greyColor
                ),
                textStyle = smsCodeEnterStyle,
                singleLine = true,
                value = enteredNumbers[index],
                onValueChange = { value: String ->
                    if (value.isDigitsOnly()) {
                        if (value.length > 1) {
                            enteredNumbers[index]  = value.last().toString()
                            return@TextField
                        }
                        if (focusRequesters[index].freeFocus()) {
                            enteredNumbers[index] = value
                            if (enteredNumbers[index].isBlank() && index > 0 && index <5) {
                                focusRequesters[index - 1].requestFocus()
                            } else if (index < smsCodeLength - 1) {
                                focusRequesters[index + 1].requestFocus()
                            }
                            else if (enteredNumbers.size == 5){
                                whenFull(enteredNumbers.joinToString(separator = ""))
                            }
                        }
                    }
                },
                keyboardOptions = KeyboardOptions.Default.copy(
                    keyboardType = KeyboardType.Number,
                    imeAction = ImeAction.Next
                ),
            )
            Spacer(modifier = Modifier.width(4.dp))
        }
    }
}
Run Code Online (Sandbox Code Playgroud)