我尝试使用与Java中相同的方法引用:
button.setOnClickListener(this::clickListener);
使用Kotlin:
button.setOnClickListener {this::clickListener}
但是这在Kotlin中不起作用,解决方案是使用labmda表达式实际调用该函数:
button.setOnClickListener {clickListener()}
为什么Kotlin在这种情况下不接受方法引用?与Java的原理不同吗?
答案 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,如果您有多个将其用作侦听器的视图。
如果您使用的是方法,则下一个取决于方法。
var
或val
函数如果您的回调定义为:
val listener = {view: View ->
TODO()
}
您可以像传递参数一样传递它:
button.setOnClickListener(listener)
如果您有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){}