Search code examples
androidkotlinlistener

Proper way to add a custom listener to a Kotlin class


I'm a Kotlin noob (third day) and trying to add a listener to my class.

I'm currently using lambdas as in the following example and they work fine.

// Declare callback
class Controller {
   var onAction = { -> }
}

// Use callback
myController.onAction = {
   ...
}

However, I really like the way Android's Button::setOnClickListener is consumed in Kotlin code as follows (without having to use =):

myButton.setOnClickListener {
    awesomeObject.doSomething()
}

This makes me wonder:

How do I declare my listener so it can be used the Button::setOnClickListener way?

What is the most 'Kotlinic'(*) way? Mine or Button::setOnClickListener way?

(*) As in Pythonic :)


Solution

  • fun setOnAction(block: () -> Unit) { onAction = block } and keep your onAction var.

    But I suppose it's more Kotlin-idiomatic to just keep what you have. Properties are usually preferred over setter funs. The Android Button syntax is the result of SAM conversion of Java code. setOnClickListener ends up more concise than onClickListener = only because with the latter, the listener is a Java interface you have to name rather than a Kotlin function. It's really verbose to write:

    button.onClickListener = OnClickListener {
        //...
    }
    

    so the SAM conversion is nicer to use.