Kun*_*nte 5 kotlin kotlin-interop
我正在尝试将一个侦听器从一个动作传递给一个类(一个适配器).
在java中(来自Action的代码):
private void setListeners() {
adapterRecyclerView.setListener(
new View.OnClickListener() {
@Override
public void onClick(View v) {
SomeCodehere....
}
});
}
Run Code Online (Sandbox Code Playgroud)
(来自适配器的代码)
public void setListener(View.OnClickListener listener) {
this.listener = listener;
}
Run Code Online (Sandbox Code Playgroud)
有用.
现在我正试图转向kotlin.我首先翻译动作(将动作翻译为kotlin):
private fun setListeners() {
// !! is not fine i know
adapterRecyclerView!!.setListener { v ->
SomeCodehere....
}
}
Run Code Online (Sandbox Code Playgroud)
此时仍然有效.适配器的代码仍然在java和kotlin中的类的代码.现在我将适配器翻译为kotlin:
fun setListener(listener: View.OnClickListener) {
this.listener = listener
}
Run Code Online (Sandbox Code Playgroud)
现在它不起作用.Action没有编译.
错误:无法推断此参数"v"的类型.必需的View.OnClickListener.发现(???)单位.
我该怎么做演员?为什么将参数从kotlin传递给java工作,从kotlin传递给kotlin它不是?
Jay*_*ard 11
在调用Java代码的情况下,您可以从使用Java编写的单个方法接口进行SAM转换.然后,当您将接口移植到Kotlin时,它还不允许这样做(Kotlin目前假设您将使用函数引用和lambdas而不是单个方法接口).
问题与其他类似问题相同:Android - Kotlin - 对象必须声明为抽象或实现抽象成员
由于这是一个Kotin界面,因此您不能将SAM转换用于Lambda,这就是为什么之前提供的其他答案不起作用的原因.如果这是一个Java接口,你可以这样做.您可以在KT-7770中跟踪Kotlin接口的SAM转换.
如果你想让这个代码更加惯用Kotlin你需要函数引用或lambdas而不是接口,你应该这样做而不是依赖于SAM转换.您可以在高阶函数和Lambdas中阅读更多相关信息.更详细地说,这超出了您的问题的范围.
因此,如@joakim的另一个答案所述,您必须传入实现此接口的类的实例.这称为对象表达式,如下所示:
object : View.OnClickListener {
override fun onClick(v: View) {...}
})
Run Code Online (Sandbox Code Playgroud)
或者实际上你应该更改代码的Kotlin端口以接受对函数的引用,以便可以直接传入lambda.这将是更惯用的,你可以像原来的尝试一样调用它.
更改
adapterRecyclerView!!.setListener { v ->
SomeCodehere....
}
Run Code Online (Sandbox Code Playgroud)
至
adapterRecyclerView!!.setListener(object : View.OnClickListener {
})
Run Code Online (Sandbox Code Playgroud)
并实现View.OnClickListener的方法
归档时间: |
|
查看次数: |
7167 次 |
最近记录: |