El peligro de usar kotlin.syntetic para el bloque en el layout

Foto de Justin Chrn en Unsplash

Ahora, con la llegada de Kotlin al desarrollo para Android, ha aparecido una útil herramienta para enlazar vistas desde el xml-layout a la clase. Se trata de kotlinx.android.synthetic. Ya no es necesario utilizar el método findViewById(). Basta con escribir el valor del id, que se especifica en el xml, y se puede utilizar la vista en la clase.Hay muchos artículos sobre esto, como la descripción oficial, por ejemplo. Pero puede haber problemas no evidentes con el uso de la etiqueta <include> en el diseño. Vamos a crear un pequeño ejemplo y tratar de mostrar tal caso.

La aplicación de prueba es la lista con dos elementos, cada uno contiene un botón con el texto. Al principio crearemos diseños para los elementos – item1.xml y item2.xml. El fondo detrás del botón tiene diferentes colores para una visibilidad más útil.

Centrémonos en que los botones en los ítems tienen el mismo id «botón». Es algo importante.

A continuación, añadir esos elementos a main_layout con ayuda <include> etiqueta:

Ahora vamos a utilizar en la clase como diseño:

Ejecutar la aplicación para obtener el siguiente resultado:

Identificación del problema

Ahora hagamos una pequeña característica, y cambiemos el texto de los botones en el código. Habrá un nuevo texto «Changed Text First Item» para el primer botón, y «Changed Text Second Item» para el segundo. Para la vinculación a los botones se utilizará kotlinx.synthetic con el alias:

import kotlinx.android.synthetic.main.item1.button as button1
import kotlinx.android.synthetic.main.item2.button as button2

Es obvio que el botón1 es la vista de item1.xml, el botón2 de item2.xml. A continuación cambiamos el texto en OnCreate:

Ejecutamos la aplicación y vemos el resultado:

¡Oops! No es lo que esperábamos. El texto del primer botón fue cambiado al texto que fue escrito para el segundo, y el texto del segundo botón no cambió absolutamente.

Explicación del problema

Tratemos de entender cuál es la razón de este resultado. Ahora ver cómo el trabajo sintético bajo el capó. Para ello descompilar clase kotlin a Java (Mostrar Kotlin Bytecode -> Descompilar para AndroidStudio). Ahora MainActivity se ve así:

Ahora podemos entender cómo el sintético es el trabajo. La actividad tiene un HashMap, que utiliza el id de la vista como clave, y el objeto de la vista como valor. Se llena por la inicialización perezosa. En nuestro caso, la primera llamada a button1 busca el valor del HashMap por la clave id = R.id.button. Como todavía no existe tal valor, el método añade un par al mapa, donde id es la clave, y un objeto-botón de item1 como valor. Como resultado, el texto para el primer botón se aplica con éxito.

La llamada a button2, que también tiene id = R.id.button, comprueba el valor del mapa para esta clave, encuentra nuestro primer View (el botón del primer elemento), y lo rellena con el valor del segundo botón. Como resultado el primer botón cambia el texto dos veces, el segundo no una vez

Solución del problema

Como primera, puedes usar diferentes id para cada vista. Pero si no es útil, puedes volver a findViewById:

Ejecutamos la aplicación y vemos el resultado:

¡Ahora funciona correctamente!

Conclusión

Las nuevas características del lenguaje dan un lof ot útil, pero usted debe entender cómo funciona para evitar problemas.

¡Gracias por leer este artículo! Espero que te sea útil

Deja un comentario