什么时候在 setOnClickListener 中写入 () 或 {}? Android 工作室

When do write inside () or {} on setOnClickListener? Android Studio

我有这两个例子,但我不明白为什么要使用冒号或大括号

  binding.playButton.setOnClickListener(
            Navigation.createNavigateOnClickListener(R.id.action_titleFragment_to_gameFragment)
    )

   binding.playButton.setOnClickListener { view: View ->
            Navigation.findNavController(view).navigate(R.id.action_titleFragment_to_gameFragment)

    }

第一种情况 - 应该监听多个视图的单击监听器:

val clickListener = { view: View ->
        when (view.tag) { // or view.id
            // ...
        }
    }
binding.playButton.setOnClickListener(clickListener)
binding.pauseButton.setOnClickListener(clickListener)

第二种情况 - 仅用于一个按钮的侦听器:

binding.playButton.setOnClickListener { view -> 
     startPlaying()
}

看起来你有一些听众工厂之王,所以第一种方法更可取。

简单的答案是用大括号{}写一段代码(多行),用括号()写一行

如果有帮助,View.OnClickListener 是一个接口,所以当您调用 setOnClickListener 时,您提供了该接口的实现:

binding.playButton.setOnClickListener(object: View.OnClickListener {
    override fun onClick(p0: View?) {
        TODO("Not yet implemented")
    }
})

因此,在此示例中,您将创建一个实现接口的对象(如匿名 class),其主体包含您需要重写的函数。您在 setOnClickListener 方法调用中将此对象作为参数传递。 (这基本上就是你第一个例子中发生的事情,你只是调用另一个函数来为你生成对象)


但是因为这个接口里面只有一个函数,所以你可以把这整个东西剥离成一个 lambda,就像一个匿名函数。只要它与接口中单个函数的签名相匹配,它就被接受为一个实现!

binding.playButton.setOnClickListener({ p0 -> TODO("Not yet implemented") })

当它是像这样的单个参数时,您可以删除变量名,它只会被称为 it,如果您的代码需要引用它(如果参数超过 1 个,您将不过需要明确命名)

binding.playButton.setOnClickListener({ TODO("Not yet implemented") })

该函数包含在大括号中,它是一个代码块。所以我们同时拥有 - 圆括号(因为我们正在进行方法调用)和大括号(分隔我们作为参数传递给方法的函数)。


但是 Kotlin 还允许我们将像这样的函数参数移到括号外,如果它是我们正在进行的调用中的最后一个参数。因此,如果您正在制作这样的正方形列表:

nums = List(4, { it * it })

你可以把初始化函数移到外面让它更整洁

nums = List(4) { it * it }

当函数是唯一参数时,您可以完全去掉括号

nums.map { it * it } // equivalent to nums.map({it * it})

这就是您的第二个示例所发生的情况 - 您正在创建一个 lambda,它是点击侦听器接口的实现,并将其传递给 setOnClickListener,因为它是您要删除的唯一参数括号,你只剩下花括号中的 lambda

binding.playButton.setOnClickListener { TODO("Not yet implemented") }

希望一切顺利! linter 通常会给你一些提示和快速修复,以将内容清理成首选样式