How use extension function when has anonymous class and method?

How use extension function with anonymous class and lambda?

eg:
TextView has this extension function: (addTextChangedListener)

inline fun TextView.addTextChangedListener(
    crossinline beforeTextChanged: (
        text: CharSequence?,
        start: Int,
        count: Int,
        after: Int
    ) -> Unit = { _, _, _, _ -> },
    crossinline onTextChanged: (
        text: CharSequence?,
        start: Int,
        count: Int,
        after: Int
    ) -> Unit = { _, _, _, _ -> },
    crossinline afterTextChanged: (text: Editable?) -> Unit = {}
): TextWatcher {
    val textWatcher = object : TextWatcher {
        override fun afterTextChanged(s: Editable?) {
            afterTextChanged.invoke(s)
        }

        override fun beforeTextChanged(text: CharSequence?, start: Int, count: Int, after: Int) {
            beforeTextChanged.invoke(text, start, count, after)
        }

        override fun onTextChanged(text: CharSequence?, start: Int, before: Int, count: Int) {
            onTextChanged.invoke(text, start, before, count)
        }
    }
    addTextChangedListener(textWatcher)

    return textWatcher
}

I can use this extension function with lambda like:

myTextView.addTextChangedListener {

}

How I call afterTextChanged, beforeTextChanged and onTextChanged using that?

You can call the function with

myTextView.addTextChagnedListener(
     {_, _, _, _ -> TODO("beforeTextChanged") }, 
     {_, _, _, _ -> TODO("onTextChanged") },
     {_ -> TODO("afterTextChanged") })

With lambdas in kotlin you don’t have to surround the last argument with parenthesis if it’s a lambda
so

myTextView.addTextChagnedListener(
     {_, _, _, _ -> TODO("beforeTextChanged") }, 
     {_, _, _, _ -> TODO("onTextChanged") })  { _ -> 
    TODO("afterTextChanged") 
}

would be correct as well. I personally prefer the first version when passing multiple lambdas, but this is just my preference.

1 Like

When passing multiple lambda arguments, consider using named arguments like so:

myTextView.addTextChagnedListener(
  beforeTextChanged = { _, _, _, _ ->
    TODO() 
  },
  afterTextChanged = { _ -> 
    TODO() 
  }
)
5 Likes