12

I have a EditText in which I want to display currency:

    input.setInputType(InputType.TYPE_CLASS_NUMBER);
    input.addTextChangedListener(new CurrencyTextWatcher());

with:

public class CurrencyTextWatcher implements TextWatcher {

boolean mEditing;

public CurrencyTextWatcher() {
    mEditing = false;
}

public synchronized void afterTextChanged(Editable s) {
    if(!mEditing) {
        mEditing = true;

        String digits = s.toString().replaceAll("\\D", "");
        NumberFormat nf = NumberFormat.getCurrencyInstance();

        try{
            String formatted = nf.format(Double.parseDouble(digits)/100);
            s.replace(0, s.length(), formatted);
        } catch (NumberFormatException nfe) {
            s.clear();
        }

        mEditing = false;
    }
}

I want to user to see a number-only keyboard, that is why I call

input.setInputType(InputType.TYPE_CLASS_NUMBER);

on my EditText. However, it does not work. I see the numbers as typed in without any formatting. BUT: If I DO NOT set the inputType via input.setInputType(InputType.TYPE_CLASS_NUMBER), the formatting works perfectly. But the user must use the regular keyboard, which is not nice. How can I use the number keyboard and also see the correct currency formatting in my EditText? Thanks.

tw-S
  • 579
  • 1
  • 5
  • 23

2 Answers2

24

It is better to use InputFilter interface. Much easier to handle any kind of inputs by using regex. My solution for currency input format:

public class CurrencyFormatInputFilter implements InputFilter {

Pattern mPattern = Pattern.compile("(0|[1-9]+[0-9]*)?(\\.[0-9]{0,2})?");

@Override
public CharSequence filter(
        CharSequence source,
        int start,
        int end,
        Spanned dest,
        int dstart,
        int dend) {

    String result = 
            dest.subSequence(0, dstart)
            + source.toString() 
            + dest.subSequence(dend, dest.length());

    Matcher matcher = mPattern.matcher(result);

    if (!matcher.matches()) return dest.subSequence(dstart, dend);

    return null;
}
}

Valid: 0.00, 0.0, 10.00, 111.1
Invalid: 0, 0.000, 111, 10, 010.00, 01.0

How to use:

editText.setFilters(new InputFilter[] {new CurrencyFormatInputFilter()});
Mussa
  • 1,463
  • 21
  • 25
  • 10
    Good approach, but the pattern given doesn't actually allow entering a decimal point, e.g. "12." so you can't actually input the fraction, you can't delete the first digit once entered, or type only a fraction ".12". A pattern that fixes these issues: "(0|[1-9]+[0-9]*)?(\\.[0-9]{0,2})?" – Sofi Software LLC Apr 08 '13 at 19:37
6

Try add this property in you xml declaration for you edit text:

android:inputType="numberDecimal" or number or signed number

See more info about android:inputType here.

kenorb
  • 155,785
  • 88
  • 678
  • 743
Lukap
  • 31,523
  • 64
  • 157
  • 244
  • This is very strange: None of your suggestions works, but I tried to put android:inputType="phone" and this gives the right formatting. However, phone-type has the "?#+" key which is not very nice. Any suggestions? – tw-S Oct 02 '11 at 16:01
  • 4
    you can add android:digits="0123456789" to forbid entering non-digit characters – kzotin Nov 22 '11 at 17:06
  • `android:inputType="numberDecimal"` is absolutely the best answer for this particular use case. – FoggyDay Feb 15 '20 at 20:34