Я форматирую текстовое поле редактирования в соответствии с форматом американской валюты, где при наборе числа в поле, скажем, «12345678», оно выглядит как «12 345 678».Для этого я использовал TextWatcher
и по методу afterTextChanged(...)
я форматирую введенный текст как:
@Override
public void afterTextChanged(Editable editable) {
String str = editable.toString();
String number = str.replaceAll("[,]", "");
if (number.equals(previousNumber) || number.isEmpty()) {
return;
}
previousNumber = number;
DecimalFormat formatter = new DecimalFormat("#,###.##", new DecimalFormatSymbols(Locale.US));
String formattedString = formatter.format(number);
editText.setText(formattedString);
}
Также я использую onSelectionChanged(...)
метод обратного вызова, например:
@Override
protected void onSelectionChanged(int selStart, int selEnd) {
this.setSelection(selStart);
}
Но здесь этот selStart не возвращает фактическую длину числа, поскольку исключает число «,» в каждой валюте.Например: для «12 345 678» возвращается число 8 вместо 10. Поэтому я не могу поместить курсор в конец поля.
Ниже приведен код пользовательского EditText, которым я являюсьиспользуя:
public class CurrencyEditText extends AppCompatEditText {
private static final int MAX_LENGTH = 16;
private static final int MAX_DECIMAL_DIGIT = 2;
private static String prefix = "";
private CurrencyTextWatcher currencyTextWatcher = new CurrencyTextWatcher(this, prefix);
public CurrencyEditText(Context context) {
this(context, null);
}
public CurrencyEditText(Context context, AttributeSet attrs) {
this(context, attrs, android.support.v7.appcompat.R.attr.editTextStyle);
}
public CurrencyEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL);
}
@Override
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
super.onFocusChanged(focused, direction, previouslyFocusedRect);
if (focused) {
this.addTextChangedListener(currencyTextWatcher);
} else {
this.removeTextChangedListener(currencyTextWatcher);
}
handleCaseCurrencyEmpty(focused);
}
private void handleCaseCurrencyEmpty(boolean focused) {
if (!focused) {
if (getText().toString().equals(prefix)) {
setText("");
}
}
}
private static class CurrencyTextWatcher implements TextWatcher {
private final EditText editText;
DecimalFormat formatter;
private String previousNumber;
private String prefix;
Context mContext;
CurrencyTextWatcher(EditText editText, String prefix) {
this.editText = editText;
this.prefix = prefix;
formatter = new DecimalFormat("#,###.##", new DecimalFormatSymbols(Locale.US));
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable editable) {
String str = editable.toString();
String number = str.replaceAll("[,]", "");
if (number.equals(previousNumber) || number.isEmpty()) {
return;
}
previousNumber = number;
String formattedString = prefix + formatNumber(number);
editText.removeTextChangedListener(this);
editText.setText(formattedString);
//handleSelection();
editText.addTextChangedListener(this);
}
private String formatNumber(String number) {
if (number.contains(".")) {
return formatDecimal(number);
}
return formatInteger(number);
}
private String formatInteger(String str) {
BigDecimal parsed = new BigDecimal(str);
return formatter.format(parsed);
}
private String formatDecimal(String str) {
if (str.equals(".")) {
return "0.";
}
BigDecimal parsed = new BigDecimal(str);
DecimalFormat formatter = new DecimalFormat("#,##0." + getDecimalPattern(str),
new DecimalFormatSymbols(Locale.US));
formatter.setRoundingMode(RoundingMode.DOWN);
return formatter.format(parsed);
}
private String getDecimalPattern(String str) {
int decimalCount = str.length() - str.indexOf(".") - 1;
StringBuilder decimalPattern = new StringBuilder();
for (int i = 0; i < decimalCount && i < MAX_DECIMAL_DIGIT; i++) {
decimalPattern.append("0");
}
return decimalPattern.toString();
}
/*private void handleSelection() {
if (editText.getText().length() <= MAX_LENGTH) {
editText.setSelection(editText.getText().length());
}
}*/
}
@Override
protected void onSelectionChanged(int selStart, int selEnd) {
this.setSelection(selStart);
}
}
Я не хочу использовать this.setSelection(lengthOfTheEnteredText)
, потому что это создало проблему при редактировании поля!В чем может быть причина того, что onSelectionChanged(...)
не учитывает число ",", присутствующее в числе?