Способы автоформатирования текста, введенного в EditText в Kotlin Android

Мне нужно, чтобы, когда я вводил денежные суммы, то текст сразу бы форматировался в нужный мне денежный формат. Например, ввел 1000 - в editText сразу текст отображался бы как 1 000; 10000 -> 10 000; 100000 -> 100 000. При этом можно вводить не только целые значения, т.е. пользователь может ввести 10003.034 и в этом случае число должно отобразиться как 10 003,034. Локали 2: En/Rus. Есть ли относительно простой способ сделать такое? Или нужно с нуля свое кастомное вью с логикой писать? Уже много разных решений испробовал, но как правило все заканчивается крашами приложения после первого форматирования или попытке стереть текст, либо поддерживается ввод лишь целых чисел)

    editText.addTextChangedListener(object : TextWatcher {
        var current = ""
            override fun afterTextChanged(salary: Editable?) {

                /* формат */
                if (salary.toString() != current) {
                    editText.removeTextChangedListener(this)
                    val formatter = DecimalFormat()
                    val symbols = DecimalFormatSymbols.getInstance()
                    symbols.groupingSeparator = ' '
                    formatter.decimalFormatSymbols = symbols
                    val newValue = formatter.format(salary.toString().toBigDecimal()).toString()
                    current = newValue
                    editText.setText(newValue)
                    editText.setSelection(newValue.length)
                    editText.addTextChangedListener(this)
                }


            }

            override fun beforeTextChanged(salary: CharSequence?, start: Int, count: Int, after: Int) {
            }
            override fun onTextChanged(salary: CharSequence?, start: Int, before: Int, count: Int) {
            }
        })

Ответы (1 шт):

Автор решения: Eugene Krivenja

Ваш код неверен в том, что меняет текст напрямую в контроле и из-за этого вынужден переподписываться. Все проще.

Вот рабочий код для целых сумм с лимитом на разрядность для локали ru-RU.
Лимит можно убрать и переделать для десятичных и нескольких локалей.

class AmountTextWatcher(val limit: Int) : TextWatcher {
    private val formatter = NumberFormat.getIntegerInstance(Locale.forLanguageTag("ru-RU"))
    val delimiter = formatter.format(1000)[1].toString()
    override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {
    }
    override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
    }
    override fun afterTextChanged(s: Editable) {
        if (s.isNotBlank()) {
            val num = try { formatter.parse(s.toString().take(limit)) } catch (ex: ParseException) { null }
            val numStr = num?.let { formatter.format(num) } ?: ""
            if (s.toString() != numStr) {
                s.replace(0, s.length, numStr)
            }
        }
    }
}
→ Ссылка