【问题标题】:Kotlin setOnClickListener using method reference not workingKotlin setOnClickListener 使用方法参考不起作用
【发布时间】:2019-01-17 14:09:43
【问题描述】:

我尝试像在 Java 中一样使用方法引用:

button.setOnClickListener(this::clickListener);

使用 Kotlin:

button.setOnClickListener {this::clickListener}

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

button.setOnClickListener {clickListener()}

为什么 Kotlin 在这种情况下不接受方法引用?是不是和Java的原理一样?

【问题讨论】:

    标签: java android kotlin method-reference


    【解决方案1】:

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

    正如 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. 
    

    进一步阅读

    【讨论】:

      【解决方案2】:

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

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

      button.setOnClickListener(clickListener)
      

      如果要使用函数,和Java一样:

      button.setOnClickListener(this::clickListener)
      
      fun clickListener(v: View) {}
      

      【讨论】:

      • 这是有道理的。但是您建议将侦听器分配给一个变量,这不是我想要的。我想要与 Java 类似的东西,只需定义一个方法并将对该方法的引用与“this::method”作为参数传递给 setOnClickListener。
      • @FraK 的语法与当时的 Java 相同。在括号中传递this::clickListener
      • 谢谢。是的,基本上是一样的,我只是对 lambda 表达式和在 Kotlin 中使用 lambda 表达式时被抑制的括号感到困惑
      【解决方案3】:

      你可以在 kotlin 中做到这一点。用括号替换大括号。

      btn.setOnClickListener (this::clicklistener)
      
      fun clicklistener(v: View){}
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-11-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多