如何使用自定义类转换为 lambda?

GHH*_*GHH 1 lambda android kotlin

我使用 Kotlin 并练习 lambda 表达式。

正常情况下,View.setOnClickListener可以转换为lambda

普通的

textView.setOnClickListener(object :View.OnClickListener{
    override fun onClick(p0: View?) {

    }
})
Run Code Online (Sandbox Code Playgroud)

拉姆达

textView.setOnClickListener { }
Run Code Online (Sandbox Code Playgroud)

然后我复制源代码并重命名该函数

class CustomView{

    fun setCustomOnClickListener(l: CustomOnClickListener) {
        throw RuntimeException("Stub!")
    }

}

interface CustomOnClickListener {
    fun customOnClick(var1: View?)
}
Run Code Online (Sandbox Code Playgroud)

我创建了我的 customView 但它无法转换为 lambda

      val myCustomView = CustomView()

      myCustomView.setCustomOnClickListener(object :CustomOnClickListener{

          override fun customOnClick(var1: View?) {

          }
      })

  //  can't convert to 
  //  myCustomView.setCustomOnClickListener{
  //
  //  } 
Run Code Online (Sandbox Code Playgroud)

谁能解释为什么以及如何转换为 lambda 表达式?

谢谢!!

use*_*450 5

您所询问的称为 SAM 转换(将实际接口实现转换为 lambda)。SAM 代表“单一抽象方法”。

您只能对 Java 接口进行 SAM 转换(确实如此View.OnClickListener)。但你的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
    }

}
Run Code Online (Sandbox Code Playgroud)

然后你可以这样做:

inline class CustomOnClickListener(val customOnClick: (View?)->Unit)
Run Code Online (Sandbox Code Playgroud)

然后是您的自定义视图:

val myCustomView = CustomView()

myCustomView.setCustomOnClickListener(CustomOnClickListener({ it: View? ->
    // whatever your listener is supposed to do with the view, it goes here
}))
Run Code Online (Sandbox Code Playgroud)

或者,inline class您可以这样做(这仍然被认为是 Kotlin 中的实验性功能):

typealias CustomOnClickListener = (View?)->Unit
Run Code Online (Sandbox Code Playgroud)

然后是您的自定义视图:

val myCustomView = CustomView()

myCustomView.setCustomOnClickListener { it: View? ->
    // whatever your listener is supposed to do with the view, it goes here
}
Run Code Online (Sandbox Code Playgroud)

是一个例子。