Convertir llamada de function a Lambda (SAM)

En un progtwig de Android, tengo el siguiente código:

clockCheckBox.setOnClickListener((object: View.OnClickListener { override fun onClick(view: View): Unit { if (clockCheckBox.isChecked()) enableClocks() else disableClocks() } })) 

En Android Studio, aparece una información sobre herramientas que dice:

Esta inspección informa sobre un object anónimo literal que implementa una interfaz java con un único método abstracto que se puede convertir en llamada con expresión lambda.

Intenté hacer esto, pero todo lo que obtengo son errores de syntax. ¿Puedes mostrarme la syntax correcta? Tal vez debería explicar que este código está en el método onCreate de mi actividad y clockCheckBox es una variable local definida como

 val clockCheckBox = findViewById(R.id.clockCheckBox) as CheckBox 

El código anterior puede simplificarse de la siguiente manera:

 // v--- parentheses is unnecessary setOnClickListener { // v--- boolean property parenthess is unnecessary if (clockCheckBox.isChecked) enableClocks() else disableClocks() } 

puede ver la interoperabilidad de Java como más.

La forma de convertirlo es dejar solo el nombre de la interfaz y el código dentro de la function. Una image (ejemplo en este caso) vale más que mil palabras, así es como se verá:

 clockCheckBox.setOnClickListener(View.OnClickListener { if (clockCheckBox.isChecked()) enableClocks() else disableClocks() }) 

Puede leer más sobre esto en la página de documentos de kotlin .

Es útil observar detenidamente el informe de inspección y entender las convenciones de Kotlin.

Esta inspección informa un object anónimo literal que implementa una interfaz java con un único método abstracto (énfasis mío) que se puede convertir en llamada con expresión lambda.

Una de las keys de este informe es "implementar una interfaz java con un único método abstracto". Esta es la key porque los objects anónimos que implementan este tipo de interfaces se pueden escribir sucintamente como solo una lambda. En otras palabras, puede omitir el literal del object anónimo y el nombre de la interfaz y simplemente usar una lambda que se ajuste a la firma del único método abstracto.

En el caso de onClick, la firma equivalente es

  (view: View) -> Unit 

Entonces la lambda para tu ejemplo sería

 { view -> if (clockCheckBox.isChecked) enableClocks() else disableClocks() } 

Pero como no está usando 'ver' en su cuerpo lambda, 'view ->' puede ser omitido. En lugar de ver, está utilizando clockCheckBox (que es una vista en el cierre de la lambda).

Por último, cuando el último parámetro de una llamada a function es un lambda, en lugar de escribir

 myFun( { ... } ) 

En su lugar, puede escribir

 myFun { ... } 

En otras palabras, está moviendo el último parámetro, el lambda, fuera del paréntesis (los paréntesis pueden omitirse si solo hay un parámetro). Entonces tu ejemplo completo usando una lambda sería

 clockCheckBox.setOnClickListener { if(clockCheckBox.isChecked()) enableClocks() else disableClocks() } 
  • Por qué este código no fue devuelto en la label en Kotlin
  • Clase abstracta Kotlin java IllegalAccessError
  • ¿Cómo puedo llamar a los methods de extensión desde fuera de la class en la que están definidos?
  • Cómo usar la anotación de Jackson JsonSubTypes en Kotlin
  • Android Room Persistences library y Kotlin
  • Producir una list de un ResultSet
  • Notificado cuando la var lateinit se ha inicializado (Kotlin)
  • No se puede usar la biblioteca de kotlin
  • Las declaraciones destructivas de KOTLIN REPL no funcionan con Pair
  • Encabezados HTTP no devueltos en EC2
  • Cómo deshabilitar Fabric cuando se ejecuta la testing