使用缩写时如何在匿名侦听器中引用 "this"?

How to reference "this" within anonymous listeners when using short notation?

在 Kotlin 中,当使用这个简短的匿名符号 类 时,有没有办法引用监听器实例?在这种情况下,this 指的是外部上下文(例如 Activity 实例),其中定义了 view

view.setOnClickListener {
    val self: View.OnClickListener = this // Not compiling, "this" references outer context
}

当使用较长的表示法时,您显式声明要实现的接口并显式覆盖回调方法,可以通过 this:

引用侦听器
view.setOnClickListener(object: View.OnClickListener {
    override fun onClick(v: View) {
        val self: View.OnClickListener = this // Ok
    }
})

匿名 类 的简称 类 并不完全正确。它实际上是匿名函数的缩写,即 lambda。当然,在幕后它们被编译为 类,但从编程语言的角度来看,匿名函数没有身份,因此通过 this 引用它们的实例没有意义。

 val animation = object : Animation() {
        override fun applyTransformation(interpolatedTime: Float, t: Transformation) {
            val layoutParam: RelativeLayout.LayoutParams? = playerView.layoutParams as RelativeLayout.LayoutParams?
            layoutParam?.topMargin = convertDpToPixel(position, this@SurahActivity).toInt()
            playerView.layoutParams = layoutParam
        }
    }

您可以通过在 'this' 引用前添加 @ActivityName 来解决这个问题 例如,如果您的 Activity 名称是 MainActivity,则解决方案将是:

view.setOnClickListener {
    val self: View.OnClickListener = this@MainActivity 
}

有点相关 - 这是一个从听众本身中删除听众的示例,该示例是在无法引用自己所接受的答案所报告的之后出现的

    @Suppress("JoinDeclarationAndAssignment")
    fun View.foo() {
        // can't combine this with the assignment since it is referenced within the
        // body of the layout listener to remove itself
        lateinit var layoutListener: ViewTreeObserver.OnGlobalLayoutListener

        layoutListener = ViewTreeObserver.OnGlobalLayoutListener {
            // ... do something ...
            viewTreeObserver.removeOnGlobalLayoutListener(layoutListener)
        }

        viewTreeObserver.addOnGlobalLayoutListener(layoutListener)
    }

我通常不会看到 lateinit 在本地方法字段中使用,所以这对我来说不是很明显