Concrete Logo
Hamburger button

Comenzando con Data Binding

  • Blog
  • 18 de Junho de 2019
Share



En el caso de Android, se trata de un sistema operativo que permite a los desarrolladores de aplicaciones implementar de forma rápida y sencilla, con fácil mantenimiento y más testeos. Si usted no oyó, echa un vistazo a este post de Izabela que tiene una buena introducción sobre el tema. En este post, vamos a hablar un poco sobre el Data Binding, una biblioteca que vincula (mapea) y facilita el enlace de la lógica y el layout de Activity, y que forma parte del paquete Android Jetpack, más precisamente de la capa de Architecture Components. El Data Binding es una biblioteca distinta del sistema operativo y se puede utilizar desde Android 2.1 (API 7).

La herramienta es bastante poderosa, pero en este post voy a mostrar sólo los primeros pasos para utilizarla. En el proyecto de ejemplo vamos a usar el lenguaje Kotlin, configurar un proyecto inicial y crear un simple formulario. Recordando que como el foco aquí es un gatillo para dar los primeros pasos en esa biblioteca, entonces el formulario no tendrá ningún tipo de validación de campo, petición al servidor o configuración de bases de datos locales y / o externos, ok? Si usted tiene interés, el código de este proyecto está en mi Github.

CONFIGURACIÓN DEL PROYECTO

Para que el proyecto pueda soportar esta biblioteca es necesario habilitarlo de la siguiente forma:

1. Abra el archivo build.gradle a nivel de aplicación (módulo de aplicación).

2. Dentro del elemento Android, añada el siguiente elemento:

¡Y listo! 🙂

Después de hacer este pequeño cambio y sincronizar, nuestro proyecto soportará el Data Binding.

CREAR NUESTRA CLASE MODELO

Vamos a crear nuestra clase modelo bastante simple, sólo para nuestro aprendizaje, que vamos a nombrar “User”. En ella, vamos a colocar los atributos de nombre y correo electrónico. Queda así:

CREAR LAYOUT DEL FORMULARIO


En primer lugar, voy a mostrar el diseño XML del formulario sin la aplicación de la biblioteca.
En él, vamos a tener dos campos de escritura, nombre y correo electrónico:

Ahora que creamos nuestro formulario, vamos a hacer un pequeño cambio. = D

IMPLEMENTANDO LA FECHA BINDING

Vamos a añadir una etiqueta denominada layout, que será nuestra etiqueta parent (root) de nuestro XML. Queda así:

¡Y es eso! Este será el diseño para poder usar nuestra biblioteca. A continuación, vamos a implementar el elemento de fecha y voy a explicar para qué sirve y cómo utilizar.

¿Vamos a entender para qué sirven estas etiquetas que se han agregado en el diseño?

Con este cambio, se generará una clase binding (clase de conexión) automáticamente y que, por defecto, tiene la nomenclatura del nombre de ViewName + Binding y al final va a generar una clase ActivityMainBinding. Pero de dónde viene el nombre de esa clase? Del layout XML que creamos, activity_main.xml. Es decir, si creamos un layout XML llamado activity_register.xml y realizamos los mismos procedimientos anteriores, la biblioteca generará un archivo llamado ActivityRegisterBinding.

ELEMENTO DATA

En el elemento de fecha se pueden insertar las importaciones de clases como, por ejemplo, nuestra clase User. Pero ¿y si desea importar otra clase que no sea una clase de plantilla, es posible? Sí! Podemos importar, por ejemplo, la clase nativa View. Usted puede hacer las condiciones para que una vista o vista de grupo sea visible o no para el usuario. Podríamos usar las constantes View.Gone, View.VISIBLE y, entre otras cosas, utilizamos la etiqueta import.

Ahora que la clase View fue importada podemos hacer una pequeña validación de algún campo.

En el ejemplo siguiente, en EditText, voy a validar si el usuario es adulto y, si es, el campo será visible y la propiedad visibilidad recibirá el valor de la constante VISIBLE. Si no es así, la propiedad recibe el valor GONE y no será visible para el usuario.

En el elemento data podemos crear variables para que sean utilizadas dentro de nuestro layout, con objetos instanciados.

Para ello, debemos usar la etiqueta variable dentro de la etiqueta data, en la que tenemos la propiedad name, que nada más es que el nombre del objeto que vamos a trabajar dentro del XML. Después de este cambio, vamos a hacer el build del proyecto y un método se generará automáticamente, con un objeto del tipo que se declarará en la propiedad como tipo. Es en este objeto que decimos cuál será el tipo de esa variable y pasamos la clase o, para ser más preciso, todo el camino en el cual la clase se encuentra. Por ejemplo, vamos a usar la clase modelo que creamos, el usuario. El siguiente es el fragmento del código:

Después de haber creado nuestra variable, vamos a la anotación en el elemento para poder asignar un valor para él. Para ello, implementamos una anotación @ = {…} en la propiedad android: text = “” del elemento. quedaría así:

Note que en la anotación y entre las llaves @ = {} llamo a la variable user. En ella, declaramos la etiqueta y la utilizamos como un objeto para que podamos acceder a sus atributos. De esta forma, podemos dar un set en el campo de digitación o un get para obtener los datos que se han introducido. Note también que después de la anotación @ tenemos el signo de igual =. Con él, podemos recibir cambios de datos y observar los cambios realizados o no por el usuario. Esto es lo que llamamos Two-Way, pero para funcionar debemos crear una clase binding, con atributos ObservableFields. Más adelante vamos a hablar más sobre eso.

Nota: Después de haber realizado este cambio, en algunos casos, Android Studio no puede generar automáticamente esta clase, por lo que debe dar un Clean Project y, a continuación, un Rebuild Project, o incluso un Invalidate Caches / Restart. Con estos procedimientos las clases se generarán normalmente.

VINCULACIÓN DE DATOS

Después de todo ese pequeño proceso, vamos a la actividad, que vamos a vincular al layout XML.
Para ello, vamos a inflar el layout utilizando el método setContentView de la clase DataBindingUtil que fue generada cuando hicimos el cambio en el layout.
Queda así:

  1. Primero vamos a quitar el método estándar de la actividad setContentView.
  2. Luego, creamos una instancia de la clase ActivityMainBinding.

El setContentView () fue reemplazado por el DataBindingUtil.setContentView (), y este fragmento de código es la nueva forma de inflar el layout XML y hacer la vinculación del layout y el objeto que vamos a crear.

Ahora que vinculamos la Actividad y el layout XML, vamos a instanciar un objeto de la clase User, pasando como parámetros el nombre y email de un usuario cualquiera, y luego hacer el bind entre ellos. = D
por lo tanto:

Tenga en cuenta que al llamar a la variable binding llamamos también el método user (en java sería binding.setUser (user)), que se crea automáticamente a partir del nombre de la variable que creamos en el layout XML.

En seguida pasamos como parámetro el objeto user para el método y él hace que todo el hechizo ocurra, mostrando los datos en los campos de escritura.

Queda así:

Observe que los datos del usuario están en nuestro layout y no fue necesario asignar los datos del objeto user uno a uno en los elementos de la actividad, ellos fueron insertados automáticamente en las vistas.

En los tópicos anteriores hemos visto cómo es fácil asignar los datos de un objeto en los elementos de una actividad, pero ¿es posible formar un objeto con los datos de la vista en el momento en que el usuario rellena los campos? Sí! Vamos a ver ahora cómo se hace.

OBSERVABLES

Un observable es una instancia de la clase Observable, que emite un flujo de datos y / o eventos que podemos usar para emitir un dato en la vista o realizar alguna acción.

¿Por qué usar observables? Para sacar de nuestra lista de preocupaciones la creación de un algoritmo de actualización de datos en la vista.

Tipos de ObservableFields

En el Data Binding, podemos trabajar con los ObservableFields, que como el propio nombre dice, son objetos observables y se parecen a un listener que está observando (oyendo) algún cambio de entrada del usuario en un campo de la pantalla. Los tipos de ObservableFields son los siguientes:

– ObservableBoolean
– ObservableByte
– ObservableChar
– ObservableShort
– ObservableInt
– ObservableLong
– ObservableFloat
– ObservableDouble
– ObservableParcelable
– ObservableField

Vamos a crear una clase binding llamada UserBinding en la que se implementará el ObservableField. Ella se quedará así:

¿Por qué crear una clase binding?

Para poder encapsular los tipos con respecto a nuestra clase modelo. Si en nuestra pantalla tuviéramos más campos, la clase binding “reflejar” los campos como atributos. Y también para no necesitar utilizar una clase modelo, que podría tener reglas de negocio que no serían necesarias para actualizar sólo datos en la vista.

Por ejemplo:

Nuestra clase binding quedará así:

import androidx.databinding.ObservableField

Después de crear la clase UserBinding, vamos a hacer un refactoring en la aplicación.

REFACTORING

La primera modificación en el layout XML, en el cual vamos a cambiar el tipo de variable en la etiqueta, en la propiedad type = “” y, en el tipo, vamos a pasar la clase binding que creamos.

por lo tanto:

Recordando que no es necesario hacer cambios en el resto del layout, ya que la clase UserBinding tiene los mismos atributos que la clase de modelo de usuario.

Ahora vamos a cambiar la actividad. No vamos a instanciar la clase User, sino la clase UserBinding y pasar los valores en sus parámetros.

Queda así:

-¿Qué hemos hecho? Pasamos al método binding.user el objeto de la clase binding, que antes recibía una instancia de la clase User. Note que para pasar un valor a los parámetros del constructor, instanciamos un ObservableField y entre paréntesis pasamos el valor deseado del tipo que implementamos en la clase binding.

-Tenga en cuenta que los datos se han introducido normalmente.

Nota: Es probable que en el momento en que cambiamos el tipo de clase en nuestro layout XML, instanciar la clase binding en la actividad y asignar el objeto en el método binding.user, el IDE reclame que el tipo de objeto no es compatible con lo que el tipo de objeto el método está queriendo recibir. Entonces, es necesario dar un Clean Project y luego un Rebuild Project. Si es necesario, incluso un Invalidate Caches / Restart.

Ahora que hemos hecho este cambio en el código, que tal prueba de la funcionalidad del cambio de algún dato de EditText, para ver si se cambia en el objeto sin la necesidad de establecerlo manualmente?

Para eso, voy a añadir dos TextViews que van a recibir el objeto user (aquella variable que creamos en XML) y asignar en esos elementos. Usted notará que sólo cambiando / escribiendo los datos de EditText todo se cambiará automáticamente.

  1. Implementando los dos TextViews en el layout XML (activity_main):

Listo!
Después de haber implementado estos dos elementos estamos listos para probar y ver que después de haber hecho algún cambio en ambos campos (EditText), el objeto user se actualizará y por lo tanto los TextViews también.

Vea abajo:

Gracias al Observable, actualizamos el objeto y nuestra pantalla sin la necesidad de llamar a cada elemento y establecer los datos e incluso sin necesidad de algún evento de click, por ejemplo.

Y para obtener ese objeto binding, ¿cómo lo haríamos? En este ejemplo, vamos a obtener el objeto después del clic del botón de registro. Es bastante simple, basta con llamar a la variable binding que está en la actividad y llamar al mismo método al que asignamos el objeto. Él servirá como un get ().

Creamos un registro sólo para poder ver los valores. Y después de presionar el botón, se creó el registro y se mostraron los datos.

¿Y es posible utilizar en un fragmento? Una vez más … ¡sí! Vamos a ver un ejemplo.

FRAGMENT CON FECHA BINDING

He creado un simple fragmento, llamado MainFragment, ya partir de él voy a hacer un pequeño refactoring. A continuación tenemos el código de la clase y del XML.

Después de la creación del fragmento, vamos a hacer un pequeño refactoring para que podamos utilizar el Data Binding. No voy a entrar mucho en detalles, pues el concepto es el mismo de la actividad.

REFACTORING

En primer lugar, vamos a hacer ese cambio en el XML que ya conocemos. Queda así:

Después de cambiar el diseño, es necesario construir el proyecto.

Ahora vamos a cambiar el fragmento:

Observe que inflamos el diseño llamando al método estático inflate () de la clase DataBindingUtil, y es a partir de él que hacemos el enlace. Este método devuelve una instancia ViewDataBinding del diseño inflado. Pasamos por parámetro el LayoutInflater, el archivo de layout, la ViewGroup y un boolean.

Después de haber inflado, llamamos a la variable binding y asignamos una instancia de la clase UserBinding, pasando nombre y email del usuario, como hicimos en el ejemplo anterior con Activity.

Sin embargo, el método onCreateView () necesita una vista como retorno, y la propia biblioteca tiene esta función que devuelve esa vista, la llamada root. Llamamos este método a partir de la variable binding y asignamos en el return del método onCreateView (). Listo! Este fue un pequeño ejemplo de cómo utilizar la biblioteca fragmentada.

¡Y eso es, personal!
Vimos en este post los conceptos básicos del Data Binding y lo que podemos hacer con él.

Si desea saber más acerca de esta biblioteca, recomiendo echar un vistazo a la documentación oficial aquí.

Recordando que este proyecto está disponible en mi Github. ¡Echa un vistazo! = D

Luego vuelveré a hablar sobre el Data Binding con proyectos más complejos y ejemplos prácticos. ¿Tiene alguna duda o contribución? Utilice los siguientes campos. ¡Hasta la próxima!