Skip to content

Instantly share code, notes, and snippets.

@ahulyk
Last active February 22, 2019 13:12
Show Gist options
  • Save ahulyk/233a33f3b9f2a6c30efd9ed8c3e33955 to your computer and use it in GitHub Desktop.
Save ahulyk/233a33f3b9f2a6c30efd9ed8c3e33955 to your computer and use it in GitHub Desktop.
Format number in android EditText after editing
package com.toastme.widget
import android.text.Editable
import android.text.TextWatcher
import android.widget.EditText
import java.math.BigDecimal
import java.text.DecimalFormat
class NumberTextWatcher(private val editText: EditText) : TextWatcher {
private val f = DecimalFormat("#$GROUP_SYMBOL###$DECI_SYMBOL##").apply {
isDecimalSeparatorAlwaysShown = true
}
private val fNoDecimal = DecimalFormat("#$GROUP_SYMBOL###")
private var hasFractionalPart = false
override fun afterTextChanged(s: Editable) {
editText.removeTextChangedListener(this)
try {
val initLen: Int = editText.text.length
val cursorPos = editText.selectionStart
val number = BigDecimal(s.replace(SEPARATOR_REGEX, ""))
editText.setText(if (hasFractionalPart) f.format(number) else fNoDecimal.format(number))
val endLen: Int = editText.text.length
val sel = cursorPos + (endLen - initLen)
if (sel > 0 && sel <= editText.text.length) {
editText.setSelection(sel)
} else {
editText.setSelection(editText.text.length - 1)
}
} catch (e: Exception) {
// ingore
}
editText.addTextChangedListener(this)
}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
val value = s.toString()
hasFractionalPart = value.contains(DECI_SYMBOL)
&& !value.endsWith("${DECI_SYMBOL}00") //workaround to fix value like 1234.
}
companion object {
const val GROUP_SYMBOL = ","
const val DECI_SYMBOL = "."
val SEPARATOR_REGEX = GROUP_SYMBOL.toRegex()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment