0

I'm using an OutlinedTextField for the user to input a number, I want that number to be restricted to two digits. The issue is that instead of using the built in soft keyboard I'm using my own custom keyboard. It ignores my regex pattern and allows multiple digits. If I enable the text field and use the soft keyboard it works as desired.

val pattern = Regex("^\\d{1,2}\$")
                OutlinedTextField(
                    enabled = false,
                    colors = TextFieldDefaults.outlinedTextFieldColors(disabledTextColor = Color.Black, cursorColor = Color.Transparent),
                    shape = RectangleShape,
                    value = viewModel.text.largestDigit.value,
                    onValueChange = { if (it.isEmpty() || it.matches(pattern)) viewModel.text.largestDigit.value = it },
                    modifier = Modifier
                        .width(IntrinsicSize.Min)
                        .padding(horizontal = 1.dp),
                    textStyle = TextStyle(fontSize = 25.sp, textAlign = TextAlign.Center),
                    label = {
                        Text(
                            text = "Enter maximum number",
                            modifier = Modifier.fillMaxWidth(),
                            fontSize = 15.sp,
                            textAlign = TextAlign.Center
                        )
                    }

                )

@Composable
fun Keyboard(onKeyPressed: (String) -> Unit) {
    val keys = listOf("1", "2", "3", "4", "5", "6", "7", "8", "9" , "<-", "0", "Enter" )
    LazyVerticalGrid(
        modifier = Modifier
            .fillMaxWidth()
            .padding(bottom = 30.dp)
            .border(BorderStroke(1.dp, Color.Black)),

        columns = GridCells.Fixed(3),
        state = LazyGridState(),
        verticalArrangement = Arrangement.Center,
        horizontalArrangement = Arrangement.Center
    ) {
        items(12) { index ->
            ElevatedCard(
                     modifier = Modifier
                    .fillMaxWidth()
                    .wrapContentWidth()
                    .wrapContentHeight()
                    .border(BorderStroke(1.dp, Color.Black))
                    .clickable(
                        onClick = {
                            onKeyPressed(keys[index])
                        },
                    ),
                shape = RectangleShape,
                colors = CardDefaults.elevatedCardColors(containerColor = Color.Green),
                elevation = CardDefaults.cardElevation(),

            ) {
                Text(
                    text = keys[index],
                    modifier = Modifier
                        .fillMaxWidth()
                        .requiredHeight(50.dp),
                    fontSize = 30.sp,
                    fontWeight = FontWeight.Bold,
                    textAlign = TextAlign.Center
                )
            }
        }
    }
}
Keyboard(onKeyPressed = { key ->
                           when (key) {
                               "<-" -> {viewModel.text.largestDigit.value = viewModel.text.largestDigit.value.dropLast(1)}
                               "Enter" -> {
                                   TODO()
                               }
                               else -> {viewModel.text.largestDigit.value = viewModel.text.largestDigit.value + key[viewModel.answer.index.value]}
                           }
                       }
                       )

I've used this keyboard successfully elsewhere in my code but I didn't need to limit the digits. Looking for ideas.

JD74
  • 257
  • 1
  • 8

1 Answers1

1

You may want to check the condition in the viewmodel, because I think the onValueChange doesn't get called if you set the value manually. Maybe create a method updateLargestDigit() in which you update the value if the new one matches your regex.

fun updateLargestDigit(value: String) {
    if (value.matches(pattern)) {
        largestDigit.value = value
    }
}

Then, call this method instead of assigning the value directly.

tobi1805
  • 171
  • 10
  • That's what I wound up doing. I was hoping for a more direct method but there doesn't seem to be a way. Thank you for your time! – JD74 Mar 11 '23 at 23:24