首页 > 解决方案 > 如何使用自定义类转换为 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 表达式?

谢谢!!

标签: androidkotlinlambda

解决方案


您要问的是所谓的 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
}

是一个例子。


推荐阅读