Home > Software engineering >  How to pass a parameter to a extension function in Kotlin
How to pass a parameter to a extension function in Kotlin

Time:12-13

I have an extension function in kotlin to check is it a valid string or not as stated below.

fun EditText.onAfterTextChanged(listener: (String) -> Unit) {
    addTextChangedListener(object : TextWatcher {
        override fun afterTextChanged(editable: Editable?) {
            val input = editable?.toString()
            val allowedChars = context.getString(R.string.supported_digits)
            val newValue = replaceInvalidCharacters(input, allowedChars)
            if (newValue != input) {
                setText(newValue)
                setSelection(text.length)
            }
            listener(newValue)
        }

        override fun beforeTextChanged(s: CharSequence?, p1: Int, p2: Int, p3: Int) {
        }

        override fun onTextChanged(s: CharSequence?, p1: Int, p2: Int, p3: Int) {
        }
    })
}

private fun replaceInvalidCharacters(value: String?, allowedChars: String): String {
    var finalValue = value ?: ""
    if (finalValue.isNotEmpty()) {
        val lastChar = finalValue.last()
        if (!allowedChars.contains(lastChar, false)) {
            finalValue = finalValue.dropLast(1)
        }
    }
    return finalValue
}

I am using it like:

editText.onAfterTextChanged {
        val length = it.length
        if (length >= 250) {
            activity?.toast(getString(R.string.max_limit_reached))
            return@onAfterTextChanged
        }
}

Here I want to pass allowedChars as a parameter to this extension as there are different strings are there for different EditText's in the application. Like 1 EditText may allow only number's but not ,- and some edit text may allow only alphanumeric, etc. Is there any way to pass a parameter to the extension?

CodePudding user response:

What you can do is update the extension function signature by adding a parameter before the callback function. So, it'll look something like this

fun EditText.onAfterTextChanged(allowedChars: String, listener: (String) -> Unit) {
    addTextChangedListener(object : TextWatcher {
        override fun afterTextChanged(editable: Editable?) {
            val input = editable?.toString()
            val allowedChars = context.getString(R.string.supported_digits)
            val newValue = replaceInvalidCharacters(input, allowedChars)
            if (newValue != input) {
                setText(newValue)
                setSelection(text.length)
            }
            listener(newValue)
        }

        override fun beforeTextChanged(s: CharSequence?, p1: Int, p2: Int, p3: Int) {
        }

        override fun onTextChanged(s: CharSequence?, p1: Int, p2: Int, p3: Int) {
        }
    })
}

And you can call it like so:

editText.onAfterTextChanged("123abc") {
    val length = it.length
    if (length >= 250) {
        activity?.toast(getString(R.string.max_limit_reached))
        return@onAfterTextChanged
    }
}
  • Related