I'm trying to pass a listener from an action to a class (an adapter).
In java (code from the Action):
private void setListeners() {
adapterRecyclerView.setListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
SomeCodehere....
}
});
}
(code from the adapter)
public void setListener(View.OnClickListener listener) {
this.listener = listener;
}
It works.
Now I'm trying to traslate to kotlin. I translate first the action (translation the action to kotlin):
private fun setListeners() {
// !! is not fine i know
adapterRecyclerView!!.setListener { v ->
SomeCodehere....
}
}
At this point still works. With the code of the adapter still in java and code of the class in kotlin. Now I translate the adapter to kotlin:
fun setListener(listener: View.OnClickListener) {
this.listener = listener
}
Now it doesn't work. The Action does not compile.
Error: cannot infer a type for this parameter "v". required View.OnClickListener. found (???) Unit.
How I must do the cast here? Why passing the parameter from kotlin to java works and from kotlin to kotlin it does not?
In the case of calling Java code you are benefitting from SAM conversion for single method interfaces written in Java. Then when you port the interface to Kotlin it does not allow this yet (Kotlin currently assumes you would use function references and lambdas instead of a single method interface).
The problem is the same as from this other similar question: Android - Kotlin - object must be declared abstract or implement abstract member
Therefore as mentioned in another answer by @joakim, you must pass in a instance of a class that implements this interface. This is called an Object Expression and looks like:
Or realistically you should change your Kotlin port of the code to accept a reference to a function so that a lambda can be passed in directly. That would be more idiomatic and you would be able to call it as you were originally attempting.
Change
to
and implement the methods of View.OnClickListener