What I'm trying to achieve is to have an EditText
with the following behaviour:
At first, the text show:
0.00 (en_GB local) or 0,00 (fr_FR local)
When user type the number 4, the Edittext show:
0.04 (en_GB) or 0,04 (fr_FR)
When user type another 6:
0.46 (en_GB) or 0,46 (fr_FR)
Etc.
Currently my code works very fine when the local is set to en_GB, however when the local change to fr_FR, I get an infinite loop.
Here is the code:
EditText layout:
<EditText
android:id="@+id/amount_ET"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="numberDecimal"
android:maxLength="8" />
And the java code:
amountEditText = (EditText) findViewById(R.id.amount_ET);
amountEditText.setText(mValueToString());
// ensure the cursor is always in the beginning of the text.
amountEditText.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (v.hasFocus()) {
int len = amountEditText.getEditableText().toString().trim().length();
if (len > 1) {
amountEditText.setSelection(0);
amountEditText.setCursorVisible(false);
}
}
}
});
// add listener in order to intercept input on the EditText
amountEditText.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
// we only update if the value is not what we expect to avoid infinite loop
if (!s.toString().isEmpty() && !s.toString().equals(mValueToString())) {
// the cursor is always at the first position, so new char are in the beginning of the editable
updateAmountTextView(s, s.charAt(0));
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
});
}
/**
* Update the new value with the given numeral and update the given Editable with the new value.
*
* @param s
* if not null, will be updated with the formatted value.
* @param c
* the char representing the number to insert.
*/
protected void updateAmountTextView(Editable s, char c) {
Integer i = Integer.valueOf(c - 48);
mValue = mValue * 10 + i;
if (s != null) {
s.clear();
s.append(mValueToString()); // when using fr_FR local, the coma is not appended leading to a false value in the editable.
}
amountEditText.setSelection(0);
}
/**
* return the String formatted value.
*/
protected String mValueToString() {
Double d = Double.valueOf(mValue) / 100;
NumberFormat formatter = new DecimalFormat("#0.00");
return formatter.format(d);
}
Has explained in the comments of the java code, the bug is in the method updateAmountTextView()
where the Editable
refuse to take the coma.
When changing the inputType
of the EditText
to the value text
this bug doesn't occur, except I want to have a softkeyboard accepting numbers only.
I guess I should do something on the Editable
object before appending value to it but I can't find anything about this in the documentation.