android - 使用 lambda 的 Kotlin setOnClickListener 语法

标签 android kotlin lambda

在 Kotlin 中设置点击监听器时,我们可以这样写:

rollButton.setOnClickListener(
    object: View.OnClickListener {
        override fun onClick(v: View?) {
            rollDice();
        }
    }
)
SAM转换后,我们可以写:
rollButton.setOnClickListener({ v -> rollDice() })
但我注意到 kotlin 也接受:
rollButton.setOnClickListener(View.OnClickListener() { v -> rollDice() })

rollButton.setOnClickListener(View.OnClickListener { v -> rollDice() })
我想知道这里发生了什么?我的意思是 setOnClickListener应该采用 OnClickListener 的实现使用匿名类或 SAM 速记之类的东西。这是某种中间阶段还是什么?
非常感谢任何解释或资源链接。

最佳答案

对于这些示例,让接口(interface)为:

fun interface IntUser {
    fun use(value: Int)
}
SAM 转换允许您使用接口(interface)的名称,就像将 lambda 作为参数的构造函数一样。
val x = IntUser({ println(it) })
Trailing lambda syntax允许您像第二个示例一样将 lambda 移动到括号外:
val y = IntUser() { println(it) }
当 lambda 是唯一参数时使用尾随 lambda 语法时,您可以省略括号,就像在第三个示例中一样:
val z = IntUser { println(it) }
最后,SAM 转换可以做的另一件事是让您传递一个裸露的 lambda 来代替接口(interface)参数。它可以从函数参数推断类型:
rollButton.setOnClickListener {
    rollDice()
}
这里我们使用 lambda 作为唯一参数,所以我们也使用尾随 lambda 语法并省略空括号。

关于android - 使用 lambda 的 Kotlin setOnClickListener 语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66675390/

相关文章:

c# - 需要合并两个数据集合的帮助

android - 一次在多个 YuvImage 上使用 compresstojpeg 时内存不足

java - OnActivityResult 没有被调用

java - 使用 Java 8 中的供应商用泛型列表填充数组抛出删除类型的 ClassCastEx b/c

android-intent - intent.getStringExtra 不能为空 kotlin

javascript - 基本项目出现 Kotlin-Java 脚本警告

c++ - 将 lambda 传递给 STL 集时出现错误 "bad function call"

Android:对服务进行单元测试

java - 将 libgdx 中的桌面应用程序转换为 android 的步骤是什么?

java - 在 Retrofit 上观察 Observable 时发生 OnError