>

DataBinding - Cada vez menos código en nuestras clases #AndroidMeetsKotlin

Francisco Manuel López Jurado     Colaboraciones    18/05/2018





En este y el siguiente post vamos a ver los grandes cambios que nos ha proporcionado Android para actualizar los datos de nuestras aplicaciones y posteriormente visualizarlos por pantalla. En este primer artículo hablamos de Data Binding, se trata de una librería que nos permite quitarnos la preocupación de las actualizaciones de la UI en función de los cambios de los datos. De esta forma, reducimos considerablemente la cantidad de código que usamos para asignar valores, cambiar visibilidades de contenedores, colores de texto, etc.

Dicho framework se puede usar a partir de API 7 (Android 2.1) por lo que no tendrás problemas para usarla en tus apps.

Antes de nada, la app que vamos a desarrollar tendrá dos pantallas:

  • Listado con las distintas versiones de Android
  • Detalle de la versión

Sin más, ¡comenzamos!

Configuración

Los pasos para su configuración son:

  1. Habilitar Data Binding en nuestra app, para ello, simplemente añadiremos en nuestro fichero build.gradle de nuestro módulo la siguiente porción de código dentro de “android”:

  1. añadimos el plugin de kapt al mismo fichero.

  1. La siguiente dependencia

Deberás tener tu Android Studio actualizado para poder disfrutar de todas las mejoras y funcionalidades nuevas, Data Binding necesita una versión de Android Studio de 1.3 o superior.

Empieza lo bueno

Una vez hemos dejado atrás las configuraciones y sabemos qué tenemos que desarrollar, empezamos con lo que realmente importa, el código.

El modelo de nuestra app está compuesto por AndroidVersionModel y sus propiedades son:

  • id - String -
  • name -String -
  • description - String -
  • imageUrl - String -

Con respecto a la teoría, todos los XML en los que queramos introducir Data Binding deben tener la etiqueta layout. Esta etiqueta por norma general solo tendrás definiciones de los esquemas que usaremos en el mismo. En cuanto a las etiquetas que contiene tenemos:

  • data. En esta etiqueta podemos definir tanto las variables que vamos a usar en nuestro XML como importar los elementos que necesitemos. Generalmente sólo tendremos las variables que usaremos para establecer los valores en los distintos campos.
  • Elemento de tipo View. En él tendremos nuestro layout definido como siempre, no presenta ninguna limitación, por lo que podemos tener cualquier tipo de layout.

Introducirlo en nuestro primer XML

Comenzaremos con el layout del listado el cual tendrá:

  • RecyclerView. En él tendremos el listado de todas las versiones disponibles.
  • TextView. Lo usaremos como la típica “EmptyView”, con él podremos ver cómo introducir lógica en la propiedad visibility del mismo.

La etiqueta data para este layout tendrá:

  • dataList - List - Se trata de una variable que tendrá el listado de las versiones de Android.
  • 3 imports: View, List y AndroidVersionModel.

Es importante destacar que necesitamos definir todos los imports necesarios para poder usar las variables o clases en nuestra vista.

Estructura de Data Binding en de activity_main.xml

Pero… ¿Cómo usamos las variables y los imports definidos?

Siempre que queramos usar elementos de Data Binding, debemos usar la sintaxis “@{ elCodigoQueQueramos }”. Dicho esto, vamos a ver cómo haciendo uso del tamaño de la lista podremos establecer la visibilidad de los elementos:

Si el listado contenido en dataList (que también está en nuestra Activity) es vacío, se ocultará el Recycler y se mostrará el TextView con el literal “No hay elementos”.

¿Cómo pasamos las variables al XML?

Siempre que usemos Data Binding en un XML se generará automáticamente una clase encargada del bind de las vistas con las variables, por ejemplo:

activity_main.xml → ActivityMainBinding

Además, automáticamente creará los setters para las variables definidas en su etiqueta data por lo que en nuestro caso creará el setter automáticamente para nuestra variable dataList.

La forma de obtener una instancia de la clase encargada del bind es:

También podemos usar la clase genérica llamada ViewDataBinding, ésta en lugar de tener los setters específicos de nuestras variables, tiene un método genérico llamado setVariable que recibe un id con la referencia a la variable y la propia variable:

Como podemos ver, hace uso de la clase BR para obtener el id, se trata de una clase autogenerada (similar a la clase R) que genera automáticamente los ids asociados a nuestras variables definidas en los layouts con Data Binding.

Vale, ya tenemos vinculado nuestro XML con nuestras propiedades, pero…

¿Si hay cambios en los elementos, cómo tengo que notificarlos?

Existen dos formas de hacerlo:

Sin Observable

Podemos establecer en la instancia del binding la variable siempre que queramos, por lo que si por ejemplo nuestro listado de elementos sufriera cambios tendríamos que notificarlo de la siguiente forma:

Con Observable

Existen una serie de objetos Observable (ObservableBoolean, ObservableArrayList, ObservableField, etc) que nos ayudarán a no tener que establecer la variable cada vez que sufre cambios. De esta forma la UI se actualizará automáticamente al invocar al método clear().

Uso de Data Binding en Adapters

Para el caso de que el contexto no sea una Activity o un Fragment, tenemos una series de cambios en cuanto a la forma de instanciar el objeto que se encargará del bind. El código sería el siguiente:

La creación de la clase ViewHolder también sufrirá cambios, lo que nos permite ahorrar código al no tener la necesidad de referenciar las vistas ni sus posteriores seteos de textos. Sólo necesitamos pasarle la instancia del binding y posteriormente setear la variable para el mismo. El código sería:

Hay que destacar el método executePendingBinding() ya que será el encargado de enviar / establecer todos los binds que faltan por hacer de forma automáticamente y sin pequeños delays.

En cuanto al código del XML sería:

Estructura de la etiqueta layout

Uso de la variable en las vistas

String format directamente en XML

Para el String a formatear:

Podemos usarlo tal que así:

¡Extra! @BindingAdapter

Una de las características que hacen este framework bastante potente es la creación / vinculación de nuevos atributos a métodos. Por ejemplo, podríamos asociar una propiedad a un ImageView para que cargue una imagen desde internet.

Como podemos ver, con la anotación @BindingAdapter y el valor imageUrl estamos definiendo que si nos encontramos con esa propiedad en el XML, automáticamente se invocará el método loadImage. Dicho método debe ser público y estático por lo que lo tendremos en un fichero (BindingAdapterUtil.kt). Este método además hace uso de la función de extensión ya definida:

En cuanto al XML en un ImageView:

De esta forma cargaremos la imagen desde internet usando Picasso a partir de la url del objeto llamado androidVersion ya definido como variable en la etiqueta data.

Resumiendo, Data Binding nos proporciona una forma de reducir considerablemente el código de nuestra vista vinculado a los típicos seteadores de textos, cambios de visibilidades en función de variables, carga de imágenes, etc. Es importante destacar que la documentación está muy detallada y podremos ver los operadores disponibles, limitaciones del código que se puede usar en el XML, etc. El siguiente paso será completar nuestro conocimiento con más información sobre este framework (clicks, propiedades, etc) antes de adentrarnos en el desarrollo con ViewModel y LiveData proporcionados por Android Architecture Components.

El código del proyecto podéis encontrarlo en el siguiente enlace.

Espero que os haya gustado.






Sobre el autor

Francisco Manuel López Jurado   

Apasionado de la tecnología y todo lo que la rodea. Desarrollador Senior Android e iOS.