kotlin如何让setOnClickListener接受函数作为参数

在kotlin中,我们可以像这样使用setOnClickListener()

 view.setOnClickListener { println("Hello") } 

但是如果我定义我自己的接口,我只能传递匿名对象,如下所示:

 obj.setMyListener(object: MyListener() { ... }) 

我只是想知道如何让setOnClickListener()接受一个函数,而不是一个匿名对象。

根据Kotlin有关Java interop的文档,对于在Java中定义的功能接口,可以使用SAM转换。

就像Java 8一样,Kotlin支持SAM转换。 这意味着只要接口方法的参数类型与Kotlin函数的参数类型匹配,Kotlin函数文本就可以用一个非默认方法自动转换为Java接口的实现。

 val runnable = Runnable { println("This runs in a runnable") } val executor = ThreadPoolExecutor() // Java signature: void execute(Runnable command) executor.execute { println("This runs in a thread pool") } 

但是,Kotlin具有功能类型,因此SAM转换不适用于在Kotlin中定义的接口:

另请注意,此功能仅适用于Java interop; 由于Kotlin具有适当的函数类型,函数自动转换为Kotlin接口的实现是不必要的,因此不受支持。


可能的解决方案:

  1. 在Java中定义接口。 如果它是可以从Java代码使用的库/代码,那么它很有用。
  2. 使该方法接收一个函数作为参数:

     // Example listener receives a bool and return unit. fun setMyListener(listener: (isChecked: Bool) -> Unit) { ... } // Usage: obj.setMyListener { isChecked -> } 
  3. 使用类型别名(仅在Kotlin 1.1+中受支持):

     typealias MyListener = (Bool) -> Unit fun setMyListener(listener: MyListener) { ... }