当前位置: 首页 > 知识库问答 >
问题:

将侦听器对象作为函数参数传递到kotlin中

马淳
2023-03-14

我正在尝试将侦听器从操作传递给类(适配器)。

在java中(操作代码):

  private void setListeners() {
    adapterRecyclerView.setListener(
            new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    SomeCodehere....
                }
            });
}

(来自适配器的代码)

public void setListener(View.OnClickListener listener) {
    this.listener = listener;
}

它起作用了。

现在我试着翻译成kotlin。我先翻译动作(把动作翻译成kotlin):

    private fun setListeners() {
    // !! is not fine i know
    adapterRecyclerView!!.setListener  { v  ->
                          SomeCodehere....
    }
}

在这一点上仍然有效。适配器的代码仍在java中,类的代码仍在kotlin中。现在,我将适配器转换为kotlin:

fun setListener(listener: View.OnClickListener) {
    this.listener = listener 
}

现在它不起作用了。操作未编译

错误:无法推断此参数“v”的类型。必需的视图。OnClickListener。找到(???)单元

我必须如何在这里进行演员表?为什么将参数从kotlin传递给java可以工作,而从kotlin传递给kotlin则不行?

共有2个答案

华萧迟
2023-03-14

改变

adapterRecyclerView!!.setListener  { v  ->
                      SomeCodehere....
}

adapterRecyclerView!!.setListener(object : View.OnClickListener {

})

并实现View. OnClickListener的方法

景宏富
2023-03-14

更新:请参阅Kotlin SAM支持:https://kotlinlang.org/docs/java-interop.html#sam-最新信息的转换。

在调用Java代码的情况下,您将受益于用Java编写的单个方法接口的SAM转换。然后,当您将接口移植到Kotlin时,它还不允许这样做(Kotlin目前假定您将使用函数引用和lambda,而不是单个方法接口)。

这个问题与另一个类似的问题相同:Android-静态编程语言-对象必须声明为抽象或实现抽象成员

由于这是一个Kotin接口,您不能使用SAM转换为Lambda,这就是为什么之前提供的另一个答案不起作用。如果这是一个Java接口,您可以这样做。您可以在KT-7770中跟踪静态编程语言接口的SAM转换。

如果您希望这段代码成为更惯用的静态编程语言,您需要函数引用或lambda而不是接口,您应该这样做,而不是依赖SAM转换。您可以在高阶函数和Lambda中阅读更多信息。这超出了您的问题范围,无法更详细地了解。

因此,正如@joakim在另一个答案中提到的,您必须传入实现此接口的类的实例。这称为对象表达式,看起来像:

object : View.OnClickListener {
    override fun onClick(v: View) {...}
})

或者实际上,您应该更改代码的Kotlin端口以接受对函数的引用,以便可以直接传入lambda。这将更加惯用,您可以像最初尝试的那样调用它。

 类似资料:
  • 问题内容: 情况有点像- 问题在于,的值在的侦听器函数中不可见,在该函数中它可能被视为新变量。 问题答案: 您编写的代码绝对没有错。双方并应访问的,以防他们在上下文中可用的匿名 已创建。 检查警报是否为您提供了您一直在寻找的值,请确保它可以在匿名函数的范围内访问(除非您对调用旁边有更多对相同变量进行操作的代码)

  • 我试图学习功能性Kotlin,并编写了以下测试代码: 在REPL中,我可以成功调用“findBorrowerX”: 但是我如何拨打“findBorrowerX2”的电话: 并将迭代的借用器x传递给getName?? 这看起来有关联,但我不确定: Kotlin:如何将一个函数作为参数传递给另一个? 提前感谢您对此的帮助! 编辑: 下面是我想做的等效Scala代码: 也许这在科特林是不可能的?

  • 我有如下spring数据存储库界面: Postgres的函数我定义如下(但如果我做错了,我可以更改): 调用此存储库方法时,出现以下错误: 你能告诉我在postgres函数中应该使用什么类型吗?谢谢你的建议。 编辑:我不能使用本机查询上述存储库方法并将其传递到IN子句中,因为我在DB函数中有更多的逻辑、变量等。。。它必须是DB函数。

  • 问题内容: 如何在不执行“父”函数或不使用函数的情况下将函数作为参数传递?(因为我已经读到它是不安全的。) 我有这个: 它可以工作,但是问题是在调用函数时触发,而不是在函数中使用时触发。 根据我所读的内容,我可以使用来解决它,但这不是最佳实践。如何在JavaScript中将函数作为参数传递? 问题答案: 您只需要删除括号: 然后,这将传递函数而不先执行它。 这是一个例子:

  • 问题内容: 我已经熟悉Android框架和Java,并希望创建一个通用的“ NetworkHelper”类,该类可以处理大多数联网代码,使我能够从中调用网页。 我遵循了来自developer.android.com的这篇文章来创建我的网络类:http : //developer.android.com/training/basics/network- ops/connecting.html 码:

  • 问题内容: 我正在读一本教科书,我想知道我们传递给函数的参数为​​什么既不是原始的也不是用户定义的类实例。 我知道它是这两个之一。但是似乎在这里它传递了用户定义的构造方法,例如Runnable()。看来他们想在以后运行线程,但是什么时候?我认为这是合法的,但是我在Java类中从未听说过这种事情。 问题答案: 实际上,这是传递实现Runnable接口的匿名内部类的实例。在Java教程中阅读有关它们的