I want to make user inputted phone number in an editText to dynamically change format every time the user inputs a number. That is, when user inputs up to 4 digits, like 714
Here is my solution
How run in Activity/Fragment (f.e in onViewCreated):
//field in class
private val exampleIdValidator by lazy { ExampleIdWatcher(exampleIdField.editText!!) }
exampleIdField.editText?.addTextChangedListener(exampleIdValidator)
Validatior class:
import android.text.Editable
import android.text.TextWatcher
import android.widget.EditText
class ExampleIdWatcher(exampleIdInput: EditText) : TextWatcher {
private var exampleIdInput: EditText = exampleIdInput
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(userInput: CharSequence?, start: Int, before: Int, count: Int) {
if (userInput!!.isNotEmpty() && !areSpacesCorrect(userInput)) {
val stringTextWithoutWhiteSpaces: String = userInput.toString().replace(" ", "")
val textSB: StringBuilder = StringBuilder(stringTextWithoutWhiteSpaces)
when {
textSB.length > 8 -> {
setSpacesAndCursorPosition(textSB, 2, 6, 10)
}
textSB.length > 5 -> {
setSpacesAndCursorPosition(textSB, 2, 6)
}
textSB.length > 2 -> {
setSpacesAndCursorPosition(textSB, 2)
}
}
}
}
override fun afterTextChanged(s: Editable?) {
}
private fun setSpacesAndCursorPosition(textSB: StringBuilder, vararg ts: Int) {
for (t in ts) // ts is an Array
textSB.insert(t, SPACE_CHAR)
val currentCursorPosition = getCursorPosition(exampleIdInput.selectionStart)
exampleIdInput.setText(textSB.toString())
exampleIdInput.setSelection(currentCursorPosition)
}
private fun getCursorPosition(currentCursorPosition: Int): Int {
return if (EXAMPLE_ID_SPACE_CHAR_CURSOR_POSITIONS.contains(currentCursorPosition)) {
currentCursorPosition + 1
} else {
currentCursorPosition
}
}
private fun areSpacesCorrect(userInput: CharSequence?): Boolean {
EXAMPLE_ID_SPACE_CHAR_INDEXES.forEach {
if (userInput!!.length > it && userInput[it].toString() != SPACE_CHAR) {
return false
}
}
return true
}
companion object {
private val EXAMPLE_ID_SPACE_CHAR_INDEXES: List = listOf(2, 6, 10)
private val EXAMPLE_ID_SPACE_CHAR_CURSOR_POSITIONS: List = EXAMPLE_ID_SPACE_CHAR_INDEXES.map { it + 1 }
private const val SPACE_CHAR: String = " "
}
}
Layout:
Result is:
XX XXX XXX XXX