Search code examples
androidandroid-jetpack-composeandroid-compose-textfield

TextField both KeyboardType.Number and KeyboardType.Decimal allows to type decimal separator


So I need to allow only numbers to by typed in the field.

I configured TextField with:

keyboardOptions = KeyboardOptions.Default.copy(
    keyboardType = KeyboardType.Number
)

But still it allows me to type decimal separators (comma and dot)

So I don't see any difference between KeyboardType.Number and KeyboardType.Decimal, they work exactly the same...

Number

@Stable
public final val Number: KeyboardType
A keyboard type used to request an IME that is capable of inputting digits. IME may provide inputs other than digits but it is not guaranteed.

Decimal

@Stable
public final val Decimal: KeyboardType
A keyboard type used to request an IME that is capable of inputting decimals. IME should explicitly provide a decimal separator as input, which is not assured by KeyboardType.Number.

Why does it happen?


Solution

  • As explained in this issue:

    Most keyboards show a decimal separator when keyboard type is set as Number. However, it is possible that a keyboard expects TYPE_NUMBER_FLAG_DECIMAL flag in inputType to actually show a key for decimal separator.
    This change adds a new KeyboardType called Decimal that explicitly sets the required flag. Number and Decimal would essentially behave the same for most keyboards and OEMs.

    You can restrict the allowed characters using a regex pattern.

    Something like:

    val pattern = remember { Regex("^\\d+\$") }
    
    TextField(
        value = text,
        onValueChange = {
            if (it.isEmpty() || it.matches(pattern)) {
                text = it
            }
        },
        keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number)
    )