0

I am trying to create otp view where each item is individually editable, problem arises when user types fast, the input is skipped. I believe there is some delay in focus manager. Below is the code, let me know if there is any issues in the snippet itself

@Composable
@Preview
fun OtpLayout(modifier: Modifier = Modifier, otpLength: Int = 6) {
    Row(horizontalArrangement = Arrangement.SpaceBetween, modifier = modifier.fillMaxWidth()) {
        val focusManager = LocalFocusManager.current
        val list = remember {
            List(6) {
                mutableStateOf(TextFieldValue(text = "", selection = TextRange(0)))
            }
        }
        repeat(otpLength) { index ->
            key(index) {
                BasicTextField(
                    modifier = Modifier.onKeyEvent {
                        if (it.key == Key.Backspace && index > 0 && list[index].value.text.isEmpty()) {
                            focusManager.moveFocus(FocusDirection.Left)
                        }
                        true
                    },
                    maxLines = 1,
                    value = list[index].value,
                    textStyle = TextStyle(color = Color.White, fontSize = 16.sp),
                    keyboardOptions = KeyboardOptions.Default.copy(keyboardType = KeyboardType.Number),
                    onValueChange = { value ->
                        Log.e("OnValue Changed called", value.text)
                        if (value.text.length <= 1 && value.text.isDigitsOnly()) {
                            list[index].value = value
                            if (value.text != "" && index < otpLength - 1) {
                                focusManager.moveFocus(FocusDirection.Right)
                            } else if (value.text == "" && index > 0) {
                                focusManager.moveFocus(FocusDirection.Left)
                            }
                        } else if (list[index].value.text.length == 1 && index < otpLength - 1) {
                            list[index + 1].value = value.copy(text = value.text.last().toString())
                            focusManager.moveFocus(FocusDirection.Right)
                        }
                    },
                    decorationBox = { innerTextField ->
                        Box(contentAlignment = Alignment.Center,
                            modifier = Modifier
                                .size(width = 42.dp, height = 52.dp)
                                .border(width = 1.dp,
                                    color = PrimaryColor,
                                    shape = RoundedCornerShape(6.dp))
                                .background(color = Gray, shape = RoundedCornerShape(6.dp))) {
                            innerTextField()
                        }
                    }
                )
            }
        }
    }
}

sarthak gupta
  • 826
  • 4
  • 12

0 Answers0