In Android application developed using Kotlin, there have an EditText
which accepts number only which is considered as USD. The input needs to be formatted into 2 decimals so that the input needs to be formatted as below
Tried using input filter. Input filter is also used to limit max value and single decimal input entry.
editTextField.filters =
arrayOf(DecimalInputFilter())
class DecimalDigitsInputFilter() : InputFilter {
override fun filter(
source: CharSequence?,
start: Int,
end: Int,
dest: Spanned?,
dstart: Int,
dend: Int
): CharSequence? {}
}
Couldn't manage to get the number formatted. Able to restrict inputs based on the rule.
editTextField.addTextChangedListener(object : TextWatcher{
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
print("beforeTextChanged")
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
print("onTextChanged")
val inputFormatter = DecimalFormat("0.00")
inputFormatter.isDecimalSeparatorAlwaysShown = true
inputFormatter.minimumFractionDigits = 2
editTextField.setText((s.toString()).format(inputFormatter))
}
override fun afterTextChanged(s: Editable?) {
print("afterTextChanged")
}
})
This also fails.
I think the main problem is that you are setting a text to the EditText
inside of a TextWatcher
which leads to looping recursion and then stack-overflow. You should change the text wrapped in removing and adding again the TextWatcher
. Here is a simple solution:
editTextField.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
print("beforeTextChanged")
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
print("onTextChanged")
val newValue = s.toString()
.takeIf { it.isNotBlank() }
?.replace(".", "")
?.toDouble() ?: 0.0
editTextField.let {
it.removeTextChangedListener(this)
it.setText(String.format("%.2f", newValue / 100))
it.setSelection(it.text?.length ?: 0)
it.addTextChangedListener(this)
}
}
override fun afterTextChanged(s: Editable?) {
print("afterTextChanged")
}
})