首页 文章

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

提问于
浏览
10

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

view.setOnClickListener { println("Hello") }

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

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

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

1 回答

  • 13

    根据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互操作;由于Kotlin具有适当的函数类型,因此不需要将函数自动转换为Kotlin接口的实现,因此不受支持 .


    可能的解决方案:

    • 用Java定义接口 . 如果它是可以从Java代码使用的库/代码,则很有用 .

    • 使方法接收函数作为参数:

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

相关问题