我使用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转换(将实际的接口(interface)实现转换为lambda)。 SAM代表“单一抽象方法”。
您只能对Java接口(interface)(即View.OnClickListener
)进行SAM转换。但是您的CustomOnClickListener
是Kotlin界面。因此,您不能进行SAM转换。您必须使用object : CustomOnClickListener { override . . . }
实现它。您不能使用lambda。
直接从Kotlin docs:
如果要保持代码简洁,您可以做的是,而不是创建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)
然后您的自定义 View :
val myCustomView = CustomView()
myCustomView.setCustomOnClickListener(CustomOnClickListener({ it: View? ->
// whatever your listener is supposed to do with the view, it goes here
}))
或者,您可以执行以下操作,而不是使用
inline class
(在Kotlin中仍被视为实验性功能):typealias CustomOnClickListener = (View?)->Unit
然后您的自定义 View :
val myCustomView = CustomView()
myCustomView.setCustomOnClickListener { it: View? ->
// whatever your listener is supposed to do with the view, it goes here
}
Here是一个示例。