我使用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是一个示例。

10-07 19:51
查看更多