Cannot pass lambda for interface in a method call with Kotlin (like how setOnClickListener does it)

Viewed 171

I created the class:

class SomeClass {
    var listener: SomeListener? = null

    interface SomeListener {
        fun onClick(v: View?)
    }

    fun addSomeListener(l: SomeListener){
        listener = l
    }

}

And I am calling it as follows, which works fine:

SomeClass().addSomeListener(object : SomeClass.SomeListener {
            override fun onClick(v: View?) {
                // Do something
            }
        })

However, the following syntax fails in Android Studio::

  SomeClass().addSomeListener{ view ->
                // Do something
        }

Type mismatch. Required: SomeClass.SomeListener Found: () → Unit


I don't understand this, because Android's setOnClickListener method is implemented the same way:

/**
     * Register a callback to be invoked when this view is clicked. If this view is not
     * clickable, it becomes clickable.
     *
     * @param l The callback that will run
     *
     * @see #setClickable(boolean)
     */
    public void setOnClickListener(@Nullable OnClickListener l) {
        if (!isClickable()) {
            setClickable(true);
        }
        getListenerInfo().mOnClickListener = l;
    }

and...

/**
     * Interface definition for a callback to be invoked when a view is clicked.
     */
    public interface OnClickListener {
        /**
         * Called when a view has been clicked.
         *
         * @param v The view that was clicked.
         */
        void onClick(View v);
    }

that can obviously be called as:

someView.setOnClickListener { view ->
// Do something
        }

What am I missing?

1 Answers

It's calling SAM Conversions. If you want to make it work you need to add keyword fun for your interface so it will look like this :

fun interface SomeListener {
        fun onClick(v: View?)
    }

You can learn more about this by reading this accepted answer.

Related