将侦听器对象作为函数参数传递给kotlin

我试图从一个行动的一个监听器传递给一个类(一个适配器)。

在java中(来自Action的代码):

private void setListeners() { adapterRecyclerView.setListener( new View.OnClickListener() { @Override public void onClick(View v) { SomeCodehere.... } }); } 

(来自适配器的代码)

 public void setListener(View.OnClickListener listener) { this.listener = listener; } 

有用。

现在我正在试着去kotlin。 我首先翻译行动(翻译行动kotlin):

  private fun setListeners() { // !! is not fine i know adapterRecyclerView!!.setListener { v -> SomeCodehere.... } } 

此时仍然有效。 使用适配器的代码仍然在java和kotlin类中的代码。 现在我把适配器翻译成kotlin:

 fun setListener(listener: View.OnClickListener) { this.listener = listener } 

现在它不工作。 该行动不编译。

错误:无法推断此参数“v”的类型。 需要View.OnClickListener。 找到(???)单位。

我该怎么做这里的演员? 为什么从kotlin到java的参数传递参数,从kotlin到kotlin呢?

更改

 adapterRecyclerView!!.setListener { v -> SomeCodehere.... } 

 adapterRecyclerView!!.setListener(object : View.OnClickListener { }) 

并实现View.OnClickListener的方法

在调用Java代码的情况下,您可以从使用Java编写的单一方法接口的SAM转换中受益。 然后,当您将接口移植到Kotlin时,它不允许这样做(Kotlin现在假设您将使用函数引用和lambdas而不是单个方法接口)。

问题是从这个其他类似的问题相同: Android – Kotlin – 对象必须声明为抽象或实现抽象成员

由于这是一个Kotin接口,因此您不能使用SAM转换为Lambda,因此之前提供的其他答案不起作用。 如果这是一个Java界面,你可以做到这一点。 您可以在KT-7770中跟踪Kotlin接口的SAM转换。

如果你想让这个代码更加地道的Kotlin,你会想要函数引用或lambdas而不是接口,你应该这样做,而不是依靠SAM转换。 你可以在高阶函数和Lambdas中阅读更多。 这是超出你的问题的范围进入更多的细节。

因此,正如@joakim的另一个答案所述,您必须传入一个实现此接口的类的实例。 这称为对象表达式 ,如下所示:

 object : View.OnClickListener { override fun onClick(v: View) {...} }) 

或者实际上你应该改变你的代码的Kotlin端口来接受一个函数的引用,这样lambda可以被直接传入。 这会更习惯,你可以像你最初尝试的那样调用它。