android - 如何使用自定义类转换为 lambda?
问题描述
我使用 Kotlin 并练习 lambda 表达式。
在正常情况下,View.setOnClickListener
可以转换为 lambda
普通的
textView.setOnClickListener(object :View.OnClickListener{
override fun onClick(p0: View?) {
}
})
拉姆达
textView.setOnClickListener { }
然后我复制源代码并重命名函数
class CustomView{
fun setCustomOnClickListener(l: CustomOnClickListener) {
throw RuntimeException("Stub!")
}
}
interface CustomOnClickListener {
fun customOnClick(var1: View?)
}
我创建了我的 customView 但它不能转换为 lambda
val myCustomView = CustomView()
myCustomView.setCustomOnClickListener(object :CustomOnClickListener{
override fun customOnClick(var1: View?) {
}
})
// can't convert to
// myCustomView.setCustomOnClickListener{
//
// }
谁能解释为什么以及如何转换为 lambda 表达式?
谢谢!!
解决方案
您要问的是所谓的 SAM 转换(将实际的接口实现转换为 lambda)。SAM 代表“单一抽象方法”。
您只能对 Java 接口(即View.OnClickListener
)进行 SAM 转换。但是你的CustomOnClickListener
是一个 Kotlin 界面。因此,您不能进行 SAM 转换。您必须使用object : CustomOnClickListener { override . . . }
. 您不能使用 lambda。
直接来自Kotlin 文档:
请注意,此功能仅适用于 Java 互操作;由于 Kotlin 具有正确的函数类型,因此不需要将函数自动转换为 Kotlin 接口的实现,因此不受支持
如果你想保持你的代码简洁,你可以做的是,而不是创建interface CustomOnClickListener
你可以做
typealias CustomOnClickListener = (View?)->Unit
那么你的 setter 函数将是相同的。您的调用函数将是this.myListener(myView)
或者您甚至可以改用实验性内联类:
inline class CustomOnClickListener(val customOnClick: (View?)->Unit)
那么你的二传手将是
fun setListener(listener: CustomOnClickListener) { this.listener = listener }
你的调用代码将是
listener.customOnClick(someView)
编辑一些更充实的代码:
class CustomView{
var listener: CustomOnClickListener? = null
fun setCustomOnClickListener(l: CustomOnClickListener) {
listener = l
}
}
然后你可以这样做:
inline class CustomOnClickListener(val customOnClick: (View?)->Unit)
然后是您的自定义视图:
val myCustomView = CustomView()
myCustomView.setCustomOnClickListener(CustomOnClickListener({ it: View? ->
// whatever your listener is supposed to do with the view, it goes here
}))
或者,inline class
您可以这样做:
typealias CustomOnClickListener = (View?)->Unit
然后是您的自定义视图:
val myCustomView = CustomView()
myCustomView.setCustomOnClickListener { it: View? ->
// whatever your listener is supposed to do with the view, it goes here
}
这是一个例子。
推荐阅读
- tcl - 在 TCL 中声明常量的方法是什么?
- python - 我收到一个错误,提示未定义 lowercase_lines
- parsing - 接球后琶音无法返回
- node.js - 如何使用钩子使用 ReactJS 将数据表单发布到 mongoDB
- git - 上传大量文件到github
- ruby-on-rails - 使用嵌套路由创建房屋
- numpy - Numpy - 从矩阵的每一列中减去向量
- css - React + SCSS:无法使用 flexbox display-flex
- angular - 声明接口的浏览器中的角度错误
- python - 从包含 BeautifulSoup 中嵌套跨度标签的跨度标签中抓取文本