Kotlin如何使setOnClickListener接受函数作为参数 [英] How kotlin makes setOnClickListener accept functions as parameter
问题描述
在kotlin中,我们可以这样使用setOnClickListener()
:
In kotlin, we can use setOnClickListener()
like this:
view.setOnClickListener { println("Hello") }
但是,如果我定义自己的接口,则只能传递这样的匿名对象:
But if I define my own interface, I can only pass anonymous object like this:
obj.setMyListener(object: MyListener() {
...
})
我只是想知道它们如何使setOnClickListener()
接受函数而不是匿名对象.
I just wondering how they make setOnClickListener()
accept a function rather than an anonymous object.
推荐答案
根据有关 Java互操作,对于用Java定义的功能接口,您可以使用SAM转换.
According to Kotlin documentations about Java interop, for a functional interface defined in Java, you can use a SAM conversion.
就像Java 8一样,Kotlin支持SAM转换.这意味着 Kotlin函数文字可以自动转换为 Java接口的单个非默认方法的实现, 只要接口方法的参数类型与 Kotlin函数的参数类型.
Just like Java 8, Kotlin supports SAM conversions. This means that Kotlin function literals can be automatically converted into implementations of Java interfaces with a single non-default method, as long as the parameter types of the interface method match the parameter types of the Kotlin function.
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中定义的接口:
However, Kotlin has functional types, therefore SAM conversion doesn't work for interfaces defined in Kotlin:
还请注意,此功能仅适用于Java互操作.自科特林以来 具有适当的功能类型,可以将功能自动转换为 Kotlin接口的实现是不必要的,因此 不支持.
Also note that this feature works only for Java interop; since Kotlin has proper function types, automatic conversion of functions into implementations of Kotlin interfaces is unnecessary and therefore unsupported.
可能的解决方案:
- 在Java中定义接口.如果它是可以从Java代码中使用的库/代码,则很有用.
-
使方法接受函数作为参数:
- Define the interface in Java. Useful if it is a library/code that may be used from a Java code.
Make the method receive a function as argument:
// Example listener receives a bool and return unit.
fun setMyListener(listener: (isChecked: Bool) -> Unit) { ... }
// Usage:
obj.setMyListener { isChecked -> }
使用类型别名(仅Kotlin 1.1+支持):
Use type alias (only supported in Kotlin 1.1+):
typealias MyListener = (Bool) -> Unit
fun setMyListener(listener: MyListener) { ... }
这篇关于Kotlin如何使setOnClickListener接受函数作为参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!