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
}
}