androidnumeric-keypad

How do I use InputType=numberDecimal with the "phone" soft keypad?


For an EditText box, the user should only be entering valid numbers, so I am using android:inputType="numberDecimal". Unfortunately, the soft keyboard that Android brings up has numbers only along the top row, while the next three rows have various other symbols (dollar sign, percent sign, exclamation mark, space, etc). Since the numberDecimal only accepts numbers 0-9, negative sign, and decimal point, it would make more sense to use the "phone" soft keyboard (0-9 in a 3x3 grid, plus some other symbols). This would make the buttons larger and easier to hit (since it's a 4x4 grid rather than a 10x4 grid in the same screen area). Unfortunately, using android:inputType="phone" allows non-numeric characters such as parentheses

I have attempted to use android:inputType="numberDecimal|phone", but the numberDecimal aspect of the bit flag seems to be ignored. I have also tried using android:inputType="phone" in combination with android:digits="0123456789-.", but that still allows multiple negative signs or decimal points (inputType="number" has really good error checking for things like that, and won't let the user even type it in). I have also tried using android:inputType="phone" in the xml layout file, while using a DigitsKeyListener in the java code, but then that just uses the default number soft keyboard (the one that has numbers only along top row) (it appears to set InputType.TYPE_CLASS_NUMBER, which voids the InputType.TYPE_CLASS_PHONE set by the xml layout).

Writing a custom IME wouldn't work, since the user would have to select the IME as a global option outside the app.

Is there any way to use the "phone" style soft keyboard while also using the "number" restrictions on what is entered?


Solution

  • So far, what I've decided to do is extend the DigitsKeyListener and override getInputType() so that it will return InputType.TYPE_CLASS_PHONE. This allows me to use the handy filter() in DigitsKeyListener, but at the same time use the TYPE_CLASS_PHONE soft keyboard. I'm new to Android programming, but this appears to work without breaking anything. Code is something like this:

    import android.text.method.DigitsKeyListener;
    import android.text.InputType;
    public class CustomDigitsKeyListener extends DigitsKeyListener
    {
        public CustomDigitsKeyListener() {
            super(false, false);
        }
    
        public CustomDigitsKeyListener(boolean sign, boolean decimal) {
            super(sign, decimal);
        }
    
        public int getInputType() {
            return InputType.TYPE_CLASS_PHONE;
        }
    }
    

    Is there anything wrong in doing this (switching the return of getInputType() to something that the superclass didn't intend)?