I am working on a android app and I have an EditText where user can input numbers. I want to format the number using different currency formats (say ##,##,###) and I want to
After several hours of working I made a phone input mask. For istance, after entering "123456" it converts it to "+1 (234) 56". After deleting of any symbol from any position a cursor moves to a right position, not to a beginning or ending.
In Activity:
etPhone.addTextChangedListener(new PhoneWatcher(etPhone));
In class:
private class PhoneWatcher implements TextWatcher {
private static final String PHONE_MASK = "+# (###) ###-##-##";
private final char[] PHONE_MASK_ARRAY = PHONE_MASK.toCharArray();
private boolean isInTextChanged;
private boolean isInAfterTextChanged;
private EditText editText;
private int shiftCursor;
private String text;
private int cursor;
public PhoneWatcher(EditText editText) {
super();
this.editText = editText;
isInTextChanged = false;
isInAfterTextChanged = false;
}
@Override
public synchronized void beforeTextChanged(CharSequence s, int start, int count, int after) {
shiftCursor = after - count;
}
@Override
public synchronized void onTextChanged(CharSequence s, int start, int before, int count) {
if (!isInTextChanged) {
isInTextChanged = true;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
char symbol = s.charAt(i);
if (symbol >= '0' && symbol <= '9')
sb.append(symbol);
}
String digits = sb.toString();
sb.setLength(0);
int j = 0;
for (int i = 0; i < digits.length(); i++) {
char digit = digits.charAt(i);
while (j < PHONE_MASK_ARRAY.length) {
if (PHONE_MASK_ARRAY[j] == '#') {
sb.append(digit);
j++;
break;
} else {
sb.append(PHONE_MASK_ARRAY[j]);
j++;
}
}
}
cursor = editText.getSelectionStart();
text = sb.toString();
if (shiftCursor > 0) {
if (cursor > text.length())
cursor = text.length();
else {
while (cursor < PHONE_MASK_ARRAY.length && PHONE_MASK_ARRAY[cursor - 1] != '#') {
cursor++;
}
}
} else if (shiftCursor < 0) {
while (cursor > 0 && PHONE_MASK_ARRAY[cursor - 1] != '#') {
cursor--;
}
}
}
}
public synchronized void afterTextChanged(Editable s) {
if (!isInAfterTextChanged) {
isInAfterTextChanged = true;
editText.setText(text);
editText.setSelection(cursor);
isInTextChanged = false;
isInAfterTextChanged = false;
}
}
}