Android - Implementing TextWatcher With Kotlin

I’ve built the part of the app that has a field for numeric input, and goes up to five digits. Something like this:

<EditText
    android:id = "@+id/editText"
    android:inputType = "number"
    android:layout_height = "wrap_content"
    android:layout_width = "wrap_content"
    android:maxLength = "5" />

The problem was that I could put five zeros there, and the program would work. Being new to Android, I’ve Googled the question and found this StackOverflow answer. From there, it seems I need a TextWatcher implementation and attaching it to editText object.

The idea I had was to make it as native as possible for usage, just like in my previous post about passing objects through intents.

I’ve made an abstract class that implements TextWatcher and its methods.

abstract class AbstractTextWatcher(private val editText: EditText) : TextWatcher {

    override fun afterTextChanged(editable: Editable) {
        validate(editText, editText.text.toString())
    }

    override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {

    }

    override fun onTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {

    }

    abstract fun validate(editText: EditText, text: String)

}

I’ve implemented only one method, leaving other two empty since I don’t need them to work, and I’ve added abstract validate() method that should be implemented next. Now, I’ve made a utility file editTextValidatorUtil.kt that contains extension function for EditText class.

Note: I’ve never thought about this, but the way that some libraries work is just like this. You get data through parameters of abstract method, but that method is called somewhere else, so you just need to implement it. It was one of those “Aha!” moments.

Back to editTextValidatorUtil.kt file:

fun EditText.myCustomTextWatcher() {
    this.addTextChangedListener(object : AbstractTextWatcher(this) {
        override fun validate(editText: EditText, text: String) {
            // do whatever validation you want here
        }
    })
}

You can read more about instantiating an abstract class in Kotlin here.

All that’s left is to add this method to specific object:

editText.myCustomTextWatcher()

Comparing this pieces of code with those from StackOverflow, I find it much more natural to add text watchers like this.