Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android EditText - allow only one decimal separator

I want EditText to allow only characters 0123456789., where both comma and dot shall be changed to some character specified by mCurrencyFormatter.getDecimalSeparator(). The second part is achieved by filter(...) method in InputFilter below. However, I can't force EditText to prevent second comma/dot. I wanted to do this by commented code in this class, but ofc it didn't work. I know one can just write android:inputType="numberDecimal" in xml file but due to a long standing android bug it always recognized decimal separator as dot. Has anyone some idea how to prevent input of second decimal separator?

InputFilter code:

class CurrencyInputFilter implements InputFilter {
  StringBuilder sb = new StringBuilder();
  boolean decimalExists;

  @Override
  public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart,
      int dend) {
    sb.setLength(0);
    decimalExists = false;
    char c;
    // for (int i = 0; i < start - 1; i++) {
    // c = source.charAt(i);
    // if (Character.toString(c).equals(".") || Character.toString(c).equals(",")) {
    // decimalExists = true;
    // break;
    // }
    // }
    // if (!decimalExists) for (int i = end; i < source.length(); i++) {
    // c = source.charAt(i);
    // if (Character.toString(c).equals(".") || Character.toString(c).equals(",")) {
    // decimalExists = true;
    // break;
    // }
    // }

    for (int i = start; i < end; i++) {
      c = source.charAt(i);
      if (Character.isDigit(c)) sb.append(c);
      if ((Character.toString(c).equals(".") || Character.toString(c).equals(","))
          && !decimalExists) {
        sb.append(mCurrencyFormatter.getDecimalSeparator());
        // decimalExists = true;
      }
    }
    // decimalExists = false;
    return sb;
  }
}

xml of my EditText:

<EditText
    android:id="@+id/my_edit_text"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:freezesText="true"
    android:imeOptions="actionDone"
    android:digits="0123456789.,"
    android:inputType="numberDecimal"
    android:selectAllOnFocus="true"
    android:singleLine="true"
    android:textSize="16sp" />
like image 377
Seblis Avatar asked Jan 24 '14 10:01

Seblis


1 Answers

Hopefully this will help someone. I needed to do this programatically.

Method 1:

editText.setKeyListener(DigitsKeyListener.getInstance(true,true));

Method 2: (method 1 didn't work for me)

First get the default decimal separator based on device locale:

DecimalFormat format = (DecimalFormat) DecimalFormat.getInstance(Locale.getDefault());
DecimalFormatSymbols symbols=format.getDecimalFormatSymbols();
defaultSeperator=Character.toString(symbols.getDecimalSeparator());

Then in your EditText TextWatcher's afterTextChanged add:

editText.addTextChangedListener(new TextWatcher() {
        public void afterTextChanged(Editable editable) {
if(editable.toString().contains(defaultSeperator))
    editText.setKeyListener(DigitsKeyListener.getInstance("0123456789"));
else
    editText.setKeyListener(DigitsKeyListener.getInstance("0123456789" + defaultSeperator));
    }
}
like image 71
Komplot Avatar answered Sep 28 '22 06:09

Komplot