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

时间:2016-12-16 08:45:39

标签: android kotlin

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

view.setOnClickListener { println("Hello") }

但是如果我定义自己的界面,我只能传递这样的匿名对象:

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

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

1 个答案:

答案 0 :(得分:13)

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

  

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

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互操作;自从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) { ... }