Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert Function Call to Lambda (SAM)

Tags:

android

kotlin

In an android program, I have the following code:

clockCheckBox.setOnClickListener((object: View.OnClickListener {
    override fun onClick(view: View): Unit {
        if (clockCheckBox.isChecked())
            enableClocks()
        else
            disableClocks()
    }
}))

In Android Studio, a tooltip comes up that says,

This inspection reports an anonymous object literal implementing a java interface with single abstract method that can be converted into call with lambda expression.

I have tried to do this, but all I get is syntax errors. Can you show me the correct syntax? I should perhaps explain that this code is in the onCreate method of my activity and clockCheckBox is a local variable defined as

val clockCheckBox = findViewById(R.id.clockCheckBox) as CheckBox
like image 527
saulspatz Avatar asked Jan 04 '23 17:01

saulspatz


1 Answers

It's useful to take a close look at the inspection report while understanding the conventions of Kotlin.

This inspection reports an anonymous object literal implementing a java interface with single abstract method (emphasis mine) that can be converted into call with lambda expression.

One of the keys in this report is "implementing a java interface with a single abstract method". This is key because anonymous objects implementing these kinds of interfaces can be succinctly written as just a lambda. In other words, you can skip the anonymous object literal and the name of the interface and just use a lambda that conforms to the single abstract method's signature.

In the case of the onClick, the equivalent signature is

    (view: View) -> Unit

So the lambda for your example would be

{ view -> if (clockCheckBox.isChecked) enableClocks() else disableClocks() }

But since you are not using 'view' in your lambda body, 'view ->' can be omitted. Instead of view, you are using clockCheckBox (which is a View in the closure for the lambda).

Lastly, when ever a function call's last parameter is a lambda, instead of writing

myFun( { ... } )

You can instead write

myFun { ... }

In other words, you are moving the last parameter, the lambda, outside of the parenthesis (the parentheses can be omitted if there is only one parameter). So your complete example using a lambda would be

clockCheckBox.setOnClickListener { 
    if(clockCheckBox.isChecked()) enableClocks() else disableClocks()
}
like image 197
Les Avatar answered Jan 07 '23 20:01

Les