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() } 
  • Kotlin: método @JvmStatic NoClassDefFoundError / ClassNotFoundException durante la testing unitaria
  • Escriba inferencia con constructores funcionales
  • Cómo devolver el valor de la function en kotlin
  • Kotlin - ¿Cómo crear una function de alias de RxJava flatmap ()?
  • NoClassDefFoundError okhttp3.internal.io.FileSystem
  • ¿Cómo convierto un dígito Char (0-9) a su valor numérico?
  • Error de renderizado en el editor de layout de Android Studio 3.0
  • Es `foo como? Foo` un equivalente completo de 'foo como Foo? `En kotlin?
  • socket de server que escucha en el cliente frente al service de votación para la aplicación de postría instantánea de Android
  • Patrón Regex Kotlin
  • Kotlin: cómo puedo acceder a mi nueva function de extensión de class desde otro file