3

I needed to format money values entered into an EditText so I used a TextWatcher but now I have issues with backspace in soft keyboard.

Normally if you hold the backspace key in the keyboard, it keeps removing characters in EditText until there is nothing left. After adding the TextWatcher, you need to manually press the backspace button many times in order to completely get rid of all characters as holding it no longer works.

How do I fix it?

public class NumberTextWatcher implements TextWatcher {
    private final EditText et;

    public NumberTextWatcher(EditText et) {
        this.et = et;
    }

    @Override
    public void afterTextChanged(Editable s) {
        et.removeTextChangedListener(this);

        try {
            String originalString = s.toString();

            long longval;
            if (originalString.contains(",")) {
                originalString = originalString.replaceAll(",", "");
            }
            longval = Long.parseLong(originalString);

            DecimalFormat formatter = (DecimalFormat) NumberFormat.getInstance(Locale.US);
            formatter.applyPattern("#,###,###,###");
            String formattedString = formatter.format(longval);

            //setting text after format to EditText
            et.setText(formattedString);
            et.setSelection(et.getText().length());
        } catch (NumberFormatException nfe) {
            nfe.printStackTrace();
        }

        et.addTextChangedListener(this);
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {

    }
}
Vahid Amiri
  • 10,769
  • 13
  • 68
  • 113

1 Answers1

0

As per afterTextChanged(Editeable s) documents, any change happened on this EditText will be notified from this callback AND it's obvious that this callback lock back-space callback in order to get advantage of reformatting the text as you need "#,###,###,###"

Propper fix: You need to proceed with your code only and only if the input wasn't the backspace key, i.e:

   @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        if (after < count) {
            isBackspaceClicked = true;
        } else {
            isBackspaceClicked = false;
        }
    }

  @Override
    public void afterTextChanged(Editable s) {
        if (!isBackspaceClicked) {
            // Your current code
        }
     }
Ibrahim Ali
  • 1,237
  • 9
  • 20