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

时间:2019-01-17 14:09:44

标签: java android kotlin method-reference

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

button.setOnClickListener(this::clickListener);

使用Kotlin:

button.setOnClickListener {this::clickListener}

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

button.setOnClickListener {clickListener()}

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

3 个答案:

答案 0 :(得分:3)

尽管已经回答了这个问题,但我想扩展现有的答案。

正如TheWanderer所述,花括号在这里表示lambda的主体。 Kotlin支持将回调外部放在常规括号中。

此:

button.setOnClickListener {clickListener()}

等于:

button.setOnClickListener({clickListener()})

等于:

button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        clickListener();
    }
});

或(仅Java 8):

button.setOnClickListener(view -> clickListener());

TL; DR:函数参数的内容用()定义,lambda主体用{}定义(就像常规函数,类,接口等一样) )。

现在,首先,onClick方法回调采用一个view参数。如果您使用独立功能,则需要使用以下参数:

fun clickListener(view: View) { TODO("Place your listener code here") }

这是基于命名的-如果您要实现OnClickListener,只需传递this作为参数即可。您已经有了侦听器和函数,因此不需要显式定义要传递的函数。但是,如果您确实实现了OnClickListener,请确保在执行操作之前检查ID,如果您有多个将其用作侦听器的视图。

如果您使用的是方法,则下一个取决于方法。

使用varval函数

如果您的回调定义为:

val listener = {view: View -> 
       TODO()               
    }

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

button.setOnClickListener(listener)

OnClickListeners

如果您有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. 

进一步阅读

答案 1 :(得分:2)

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

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

button.setOnClickListener(clickListener)

如果要使用函数,则与Java相同:

button.setOnClickListener(this::clickListener)

fun clickListener(v: View) {}

答案 2 :(得分:1)

您可以在Kotlin中进行此操作。用括号替换大括号。

btn.setOnClickListener (this::clicklistener)

fun clicklistener(v: View){}