I want to format user's input and it's okay, but when I try to input zero after dot DecimalFormat
removes it.
I use the following code:
DecimalFormat df = new DecimalFormat("#,###.##");
Number n = df.parse(v);
amountEdit.setText(df.format(n));
Example Input/Output:
9.0 -> 9.
9.9 -> 9.9
9.90 -> 9.9
It removes zeros!
EDIT:
I have EditText
with TextChangedListener
The idea is to format user's input like 999 999 999.99
(this is max value).
amountEdit.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (data.document.isPaymentPossible) {
if (s.toString().contains(String.valueOf(df.getDecimalFormatSymbols().getDecimalSeparator())) || s.toString().contains(".")) {
hasDot = true;
} else {
hasDot = false;
}
}
}
@Override
public void afterTextChanged(Editable s) {
String string = s.toString().replaceAll("\\.", ",");
if (string.equals(",") || string.equals(".")) {
amountEdit.setText("");
return;
}
amountEdit.removeTextChangedListener(this);
payCustomAmount.setEnabled(amountEdit.getText().length() != 0);
try {
if (string.contains(",")) {
try {
String afterDot = string.split(",")[1];
if (afterDot.length() > 2) {
string = string.substring(0, string.length() - 1);
Number n = df.parse(string);
amountEdit.setText(df.format(n).replace(",", "."));
amountEdit.setSelection(amountEdit.getText().length());
amountEdit.addTextChangedListener(this);
showOverPaidText();
return;
}
} catch (Exception e) {
if (BuildConfig.DEBUG) {
SysUtils.logf("PaymentOptions input: " + s + "Exception: " + e);
}
}
} else {
if (string.length() > 11) {
string = string.substring(0, string.length() - 1);
Number n = dfnd.parse(string);
amountEdit.setText(dfnd.format(n));
amountEdit.setSelection(amountEdit.getText().length());
showOverPaidText();
amountEdit.addTextChangedListener(this);
return;
}
}
int inilen, endlen;
inilen = amountEdit.getText().length();
String v = string.replace(String.valueOf(df.getDecimalFormatSymbols().getGroupingSeparator()), "");
int cp = amountEdit.getSelectionStart();
if (hasDot) {
Number n = df.parse(v);
String ss = df.format(n).replace(",", ".");
amountEdit.setText(ss);
} else {
Number n = dfnd.parse(v);
amountEdit.setText(dfnd.format(n));
}
endlen = amountEdit.getText().length();
int sel = (cp + (endlen - inilen));
if (sel > 0 && sel <= amountEdit.getText().length()) {
amountEdit.setSelection(sel);
} else {
amountEdit.setSelection(amountEdit.getText().length() - 1);
}
} catch (NumberFormatException | ParseException e) {
showOverPaidText();
amountEdit.addTextChangedListener(this);
if (BuildConfig.DEBUG) {
SysUtils.logf("PaymentOptions input: " + s + "Exception: " + e);
}
return;
}
showOverPaidText();
amountEdit.addTextChangedListener(this);
return;
}
});
My onCreate
contains:
df = new DecimalFormat("#,###.00");
df.setDecimalSeparatorAlwaysShown(true);
dfnd = new DecimalFormat("#,###");
hasDot = false;
It removes zeros!
Well yes, it would - you've specifically used .##
which means "only include digits if they're significant". If you want to always have at least one decimal place, use
DecimalFormat df = new DecimalFormat("#,###.0#");
If you always want to have two decimal places, use:
DecimalFormat df = new DecimalFormat("#,###.00");
You should probably consider how you want 0.5 to be formatted, too. Do you want "0.5" or ".5"?
See more on this question at Stackoverflow