lunes, agosto 21, 2017

Android con Kotlin: Usando Lambda Expressions

Las expresiones lambda (o lambda expressions) que veremos en Kotlin, no son en realidad una completa novedad..., en Java se pueden usar y es algo que otros lenguajes como C# ya lo tienen desde aproximadamente el año 2006 (con .Net 3.0).

Pero, ¿que son las expresiones lambda?

Las expresiones lambda permiten pasar funcionalidad como argumento de una forma muy simple y sin tener que usar clases anónimas. Esto hace que simplifique mucho la codificación.

Supongamos que tenemos la siguiente función:

fun compare(a: String, b: String): Boolean = a.length < b.length

Mediante una expresión lambda se podría hacer los siguiente:

max(strings, { a, b -> a.length < b.length })

"max" es una función que toma el valor del segundo argumento, donde este segundo argumento es en sí, una función.

El formal en general de una expresión lambda es:

{
  param1, param2 -> //parámetros separados por coma
  param1 + param2 //código a ejecutar
}

Para terminar de ver esto con un ejemplo bien práctico, primero tomemos como referencia la implementación de un "OnItemClicListener" en un ListView en Java, tradicionalmente se vería de la siguiente manera:

mListView.setOnItemClickListener(new OnItemClickListener() {
  @Override
  public void onItemClick(AdapterView<?> parent, View view,
  int position, long id) {

  Log.d("onItemClick", "Se hizo clic") // Acá va la acción a realizar.

  }
});

Con un lambda expression en Kotlin, se simplificaría de esta manera:

mListView.onItemClickListener = AdapterView.OnItemClickListener { parent, view, position, id ->

    Log.d("onItemClick", "Se hizo clic") // Acá va la acción a realizar.

}

Como se puede apreciar, la diferencia en simplicidad y reducción de código es sumamente apreciable. No obstante, supongamos que view y id sean parámetros los cuáles no se les dará uso, la expresión podrían simplificarse aún más reemplazando esas argumentos que no estarán en uso por un "underscore":

mListView.onItemClickListener = AdapterView.OnItemClickListener { parent, _, position, _ ->

    Log.d("onItemClick", "Se hizo clic") // Acá va la acción a realizar.

}

Aún mejor, supongamos el siguiente clásico ejemplo del OnClickListener de un botón en Java:

button.setOnClickListener(new OnClickListener(){

@Override
public void onClick(View v){

doSomething();

}
});

En Kotlin, se reduce a una sola línea:

button.setOnClickListener({ view -> doSomething() })

Si los parámetros no son usados, directamente en lugar de reemplazarlos por un underscore, puede quitarlos, quedando:

button.setOnClickListener({ doSomething() })

Finalmente, como la función parámetro es única y el lambda también, puedo quitar los paréntesis quedando:

button .setOnClickListener { doSomething() }

Algo para destacar es que el mismo Android Studio nos va guiando y, si encuentra que podemos reemplazar el código que escribimos por una expresión lambda, nos lo siguiente actualizarlo en forma automática de la mano de la "lamparita amarilla" que usualmente aparece sobre el margen izquierdo de nuestro código.

Android Studio Kotlin Lambda Expression

Se puede ver un ejemplo completo e implementado de esto y otros temas más, en la siguiente aplicación que dejé completa en Github: