Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/180.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin如何实现android setOnClickListener式语法_Android_Kotlin_Functional Programming - Fatal编程技术网

Kotlin如何实现android setOnClickListener式语法

Kotlin如何实现android setOnClickListener式语法,android,kotlin,functional-programming,Android,Kotlin,Functional Programming,在Android+Kotlin中,以下两种语法均有效 view.setOnClickListener(this)和view.setOnClickListener{}我一直在尝试为我的自定义函数接口实现这种语法,但没有成功。这是我到目前为止所做的尝试 interface OnClickListener { fun onClick(str: String) } class Test { fun setClickListener(listener: OnClickListener)

Android
+
Kotlin
中,以下两种语法均有效

view.setOnClickListener(this)
view.setOnClickListener{}
我一直在尝试为我的自定义函数接口实现这种语法,但没有成功。这是我到目前为止所做的尝试

interface OnClickListener {
    fun onClick(str: String)
}

class Test {
    fun setClickListener(listener: OnClickListener) {
        listener.onClick("")
    }
}

fun main() {
    val test = Test()
    test.setClickListener { str -> 

    }
}
在上面的代码段中,
main()
中的代码无法编译,因为它需要
OnClickListener
类的匿名对象。如何实现与原始
OnClickListener
相同的客户端代码语法?

使用

fun setClickListener(listener: (String) -> Unit)
然后调用
监听器(“一些字符串”)
我喜欢做的是:

inline fun View.onClick(crossinline clickListener: (View) -> Unit) {
    this.setOnClickListener {
        clickListener(this)
    }
}
现在你可以打电话了

button.onClick {
    // handle click
}

编辑:啊,我误解了你的问题。答案是

interface OnClickListener {
    fun onClick(target: Any)
}

class Test {
    private var onClickListener: OnClickListener? = null

    fun setOnClickListener(listener: OnClickListener?) {
        this.onClickListener = listener
    }

    fun doClick() {
        onClickListener?.onClick(this)
    }
}

inline fun Test.setOnClickListener(crossinline listener: (Test) -> Unit) {
    this.setOnClickListener(object: OnClickListener {
        override fun onClick(target: Any) {
            listener.invoke(target as Test)
        }
    })
}

fun main() {
    val test = Test()
    test.setOnClickListener { t -> 
        println("hello")
    }

    test.doClick()
}

如果您仅使用Kotlin,这是不可能的。您可以通过使用JAVA的@FunctionInterface来实现这一点。无论它看起来多么不一致,它都是语言设计的产物

SAM转换似乎只适用于Java接口。根据论坛讨论,这是设计的:Kotlin有功能类型,每个人都应该使用它们。虽然这个论点是完全合理的,但这种限制确实有点不一致


请检查这个

我最近为此写了一个答案。这样我就失去了我的界面,我不想要,我仍然想要保留这个界面。这样我的课程就可以从中扩展。