Прошло более 8 лет, и я удивлен, что эта проблема еще не устранена ...
Я боролся с этой простой проблемой, поскольку наиболее одобренный ответ @Martin позволяет вводить несколько разделителей, т.е.пользователь может ввести «12 ,,,,,, 12,1,, 21,2,"
Кроме того, вторая проблема заключается в том, что на некоторых устройствах запятая не отображается нацифровая клавиатура (или требуется многократное нажатие точечной кнопки)
Вот мое обходное решение, которое решает упомянутые проблемы и позволяет пользователю вводить '.'и ',', но в EditText он увидит единственный десятичный разделитель, соответствующий текущей локали:
editText.apply { addTextChangedListener(DoubleTextChangedListener(this)) }
И наблюдатель текста:
open class DoubleTextChangedListener(private val et: EditText) : TextWatcher {
init {
et.inputType = InputType.TYPE_CLASS_NUMBER or InputType.TYPE_NUMBER_FLAG_DECIMAL
et.keyListener = DigitsKeyListener.getInstance("0123456789.,")
}
private val separator = DecimalFormatSymbols.getInstance().decimalSeparator
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
//empty
}
@CallSuper
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
et.run {
removeTextChangedListener(this@DoubleTextChangedListener)
val formatted = toLocalizedDecimal(s.toString(), separator)
setText(formatted)
setSelection(formatted.length)
addTextChangedListener(this@DoubleTextChangedListener)
}
}
override fun afterTextChanged(s: Editable?) {
// empty
}
/**
* Formats input to a decimal. Leaves the only separator (or none), which matches [separator].
* Examples:
* 1. [s]="12.12", [separator]=',' -> result= "12,12"
* 2. [s]="12.12", [separator]='.' -> result= "12.12"
* 4. [s]="12,12", [separator]='.' -> result= "12.12"
* 5. [s]="12,12,,..,,,,,34..,", [separator]=',' -> result= "12,1234"
* 6. [s]="12.12,,..,,,,,34..,", [separator]='.' -> result= "12.1234"
* 7. [s]="5" -> result= "5"
*/
private fun toLocalizedDecimal(s: String, separator: Char): String {
val cleared = s.replace(",", ".")
val splitted = cleared.split('.').filter { it.isNotBlank() }
return when (splitted.size) {
0 -> s
1 -> cleared.replace('.', separator).replaceAfter(separator, "")
2 -> splitted.joinToString(separator.toString())
else -> splitted[0]
.plus(separator)
.plus(splitted.subList(1, splitted.size - 1).joinToString(""))
}
}
}