【问题标题】:Kotlin how to achieve android setOnClickListener like syntaxKotlin如何实现android setOnClickListener之类的语法
【发布时间】:2019-10-09 19:09:43
【问题描述】:

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() 中的上述sn-p 代码中,由于需要OnClickListener 类的匿名对象,因此编译失败。如何实现与原始 OnClickListener 相同的客户端代码语法?

【问题讨论】:

标签: android kotlin functional-programming


【解决方案1】:

如果您只使用 Kotlin,这是不可能的。您可以通过使用 JAVA 的 @FunctionalInterface 来实现这一点。不管它看起来多么不一致,都是语言设计的。

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

请查看link

【讨论】:

    【解决方案2】:

    使用

    fun setClickListener(listener: (String) -> Unit)
    

    然后拨打listener("some string")

    【讨论】:

    • 这样我就失去了我的界面,我不希望我仍然想保留界面。这样我的课程就可以从中扩展。
    【解决方案3】:

    我喜欢做的是:

    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()
    }
    

    【讨论】:

      猜你喜欢
      • 2017-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-24
      • 1970-01-01
      • 2020-09-05
      相关资源
      最近更新 更多