Kotlin setOnClickListener 使用方法引用不起作用

Fra*_*raK 2 java android kotlin method-reference

我尝试以与 Java 中相同的方式使用方法引用:

button.setOnClickListener(this::clickListener);
Run Code Online (Sandbox Code Playgroud)

使用科特林:

button.setOnClickListener {this::clickListener}
Run Code Online (Sandbox Code Playgroud)

但是这在 Kotlin 中不起作用,解决方案是使用 labmda 表达式实际调用函数:

button.setOnClickListener {clickListener()}
Run Code Online (Sandbox Code Playgroud)

为什么 Kotlin 在这种情况下不接受方法引用?和Java的原理不一样吗?

Zoe*_*Zoe 6

虽然这已经得到了回答,但我想扩展现有的答案。

正如 TheWanderer 已经提到的,这里的花括号表示 lambda 的主体。Kotlin 支持将回调放在常规括号之外

这个:

button.setOnClickListener {clickListener()}
Run Code Online (Sandbox Code Playgroud)

等于:

button.setOnClickListener({clickListener()})
Run Code Online (Sandbox Code Playgroud)

这等于:

button.setOnClickListener {clickListener()}
Run Code Online (Sandbox Code Playgroud)

或(仅限 Java 8):

button.setOnClickListener({clickListener()})
Run Code Online (Sandbox Code Playgroud)

TL;DR:函数参数的内容用 定义(),而 lambda 体用 定义{}(就像普通函数、类、接口等)。

现在,首先,onClick 方法回调接受一个view参数。如果你使用一个独立的函数,它需要有这个参数:

fun clickListener(view: View) { TODO("Place your listener code here") }
Run Code Online (Sandbox Code Playgroud)

这是基于命名的——如果你正在实现OnClickListener,只需this作为参数传递。你已经有了监听器和函数,所以你不需要明确定义一个来传递。但是,如果您确实实施OnClickListener,如果您有多个视图将其用作侦听器,请确保在采取行动之前检查 ID。

如果您正在使用方法,接下来取决于如何使用。

使用varval功能

如果您的回调定义为:

val listener = {view: View -> 
       TODO()               
    }
Run Code Online (Sandbox Code Playgroud)

您可以像参数一样传递它:

button.setOnClickListener(listener)
Run Code Online (Sandbox Code Playgroud)

点击监听器

如果您有var onClickListener: OnClickListener,则与var/val功能相同。

使用函数

如果您有fun clickListener,则必须添加 lambda 才能传递它。这就像 Java 一样,使用::. 但是,您不需要像在 Java 中那样显式声明作用域。这意味着其中任何一个都可以工作:

button.setOnClickListener(::clickListener);
button.setOnClickListener(this::clickListener);
// alternatively with a different target, if it's somewhere else. 
Run Code Online (Sandbox Code Playgroud)

进一步阅读


The*_*rer 5

花括号表示 lambda 表达式的内容。Kotlin 已经在幕后传递了 OnClickListener 的一个实例,并为您提供了该onClick()方法。

如果要传递已分配给变量的侦听器,请使用括号:

button.setOnClickListener(clickListener)
Run Code Online (Sandbox Code Playgroud)

如果你想使用一个函数,它和Java一样:

button.setOnClickListener(this::clickListener)

fun clickListener(v: View) {}
Run Code Online (Sandbox Code Playgroud)