Skip to content

Instantly share code, notes, and snippets.

@sajjadyousefnia
Created May 23, 2024 17:27
Show Gist options
  • Save sajjadyousefnia/ef97fc459a78755c97cf08608b264a76 to your computer and use it in GitHub Desktop.
Save sajjadyousefnia/ef97fc459a78755c97cf08608b264a76 to your computer and use it in GitHub Desktop.
fun EditText.addThousandSeparator() {
this.addTextChangedListener(object : TextWatcher {
private var current = ""
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.toString() != current) {
val userInput = s.toString().replace("[^\\d]".toRegex(), "")
if (userInput.isNotEmpty()) {
val formatted = StringBuilder()
val symbols = DecimalFormatSymbols.getInstance()
val separator = symbols.groupingSeparator
var counter = 0
for (i in userInput.length - 1 downTo 0) {
formatted.append(userInput[i])
counter++
if (counter % 3 == 0 && i != 0) {
formatted.append(separator)
}
}
current = formatted.reverse().toString()
val selectionStart = this@addThousandSeparator.selectionStart
val newSelectionStart =
calculateCursorPosition(selectionStart, userInput, current)
this@addThousandSeparator.removeTextChangedListener(this)
this@addThousandSeparator.setText(current)
this@addThousandSeparator.setSelection(newSelectionStart)
this@addThousandSeparator.addTextChangedListener(this)
}
}
}
})
}
private fun calculateCursorPosition(
start: Int,
originalText: String,
formattedText: String
): Int {
val symbols = DecimalFormatSymbols.getInstance()
val separator = symbols.groupingSeparator
var newPosition = start
for (i in 0 until start) {
if (i < formattedText.length && formattedText[i] == separator) {
newPosition++
}
}
return newPosition.coerceAtMost(formattedText.length)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment