在Kotlin中将侦听器对象作为函数参数传递 [英] Passing a listener object as a function parameter in kotlin

查看:210
本文介绍了在Kotlin中将侦听器对象作为函数参数传递的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to pass a listener from an action to a class (an adapter).

在Java中(来自Action的代码):

In java (code from the Action):

  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):

Now I'm trying to traslate to kotlin. I translate first the action (translation the action to kotlin):

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

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

At this point still works. With the code of the adapter still in java and code of the class in kotlin. Now I translate the adapter to kotlin:

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

现在它不起作用.该操作无法编译.

Now it doesn't work. The Action does not compile.

错误: 无法推断此参数"v"的类型. 必需的View.OnClickListener. 找到(???)单位.

Error: cannot infer a type for this parameter "v". required View.OnClickListener. found (???) Unit.

在这里我该怎么做演员? 为什么不能将参数从kotlin传递给java,而不能将参数从kotlin传递给kotlin?

How I must do the cast here? Why passing the parameter from kotlin to java works and from kotlin to kotlin it does not?

推荐答案

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

In the case of calling Java code you are benefitting from SAM conversion for single method interfaces written in Java. Then when you port the interface to Kotlin it does not allow this yet (Kotlin currently assumes you would use function references and lambdas instead of a single method interface).

问题与其他类似问题相同:

The problem is the same as from this other similar question: Android - Kotlin - object must be declared abstract or implement abstract member

由于这是Kotin界面,因此您无法将SAM转换为Lambda,这就是为什么以前提供的其他答案不起作用的原因.如果这是Java接口,则可以执行此操作.您可以在 KT-7770 中跟踪Kotlin界面的SAM转换.

Since this is a Kotin interface, you cannot use the SAM conversion to a Lambda so that is why the other answer previously provided does not work. If this was a Java interface, you could do that. You can track SAM conversions for Kotlin interfaces in KT-7770.

如果您希望此代码更惯用Kotlin,则需要函数引用或lambda,而不是接口,而应该这样做而不是依赖SAM转换.您可以在高阶函数和Lambdas中了解更多信息.这不在您的问题讨论范围之内.

If you wanted this code to be more idiomatic Kotlin you would want function references or lambdas instead of interfaces, and you should just do that instead of relying on SAM conversion. You can read more about that in Higher-Order Functions and Lambdas. This is outside the scope of your question to go into more detail.

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

Therefore as mentioned in another answer by @joakim, you must pass in a instance of a class that implements this interface. This is called an Object Expression and looks like:

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

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

Or realistically you should change your Kotlin port of the code to accept a reference to a function so that a lambda can be passed in directly. That would be more idiomatic and you would be able to call it as you were originally attempting.

这篇关于在Kotlin中将侦听器对象作为函数参数传递的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆