Le danger d’utiliser kotlin.syntetic for block in layout

Photo de Justin Chrn sur Unsplash

Maintenant, avec l’avènement de Kotlin dans le développement pour Android, un outil utile est apparu pour lier les vues du xml-layout à la classe. Il s’agit de kotlinx.android.synthetic. Il n’est plus nécessaire d’utiliser la méthode findViewById(). Il suffit d’écrire la valeur de l’id, qui est spécifié dans le xml, et vous pouvez utiliser la vue dans la classe.il ya beaucoup d’articles à ce sujet, comme la description officielle par exemple. Mais il peut y avoir des problèmes non évidents avec l’utilisation de la balise <include> dans le layout. Créons un petit exemple et essayons de montrer un tel cas.

L’application de test est la liste avec deux éléments, chacun d’eux contient un bouton avec du texte. Au début va créer des mises en page pour les éléments – item1.xml et item2.xml. Le fond derrière le bouton a des couleurs différentes pour une visibilité plus utile.

Mettons l’accent sur le fait que les boutons dans les éléments ont le même id « bouton ». C’est une chose importante.

Ajouter ensuite ces éléments à main_layout avec l’aide <include> tag:

Maintenant, utilisons-le dans la classe comme layout:

Lancer l’application pour obtenir le résultat suivant :

Identification du problème

Maintenant faisons une petite fonctionnalité, et changeons le texte des boutons dans le code. Il y aura un nouveau texte « Changed Text First Item » pour le premier bouton, et « Changed Text Second Item » pour le second. Pour lier les boutons, nous utiliserons kotlinx.synthetic avec les alias:

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

Il est évident que le bouton1 est vu depuis item1.xml, le bouton2 depuis item2.xml. Changeons ensuite le texte sur OnCreate:

Exécutons l’application et voyons le résultat:

Oops ! Ce n’est pas ce que nous attendions. Le texte du premier bouton a été changé par le texte qui a été écrit pour le second, et le texte du second bouton n’a pas changé absolument.

Explication du problème

Essayons de comprendre quelle est la raison de ce résultat. Maintenant, voir comment le travail synthétique sous le capot. Pour cela, décompilez la classe kotlin en Java (Show Kotlin Bytecode -> Decompile for AndroidStudio). Maintenant, MainActivity ressemble à ceci:

Maintenant, nous pouvons comprendre comment le synthétique est de travail. Activity a HashMap, qui utilisent id de vue comme clé, et vue-objet comme valeur. Il est rempli par initialisation paresseuse. Dans notre cas, le premier appel à button1 cherche la valeur de la HashMap par la clé id = R.id.button. Comme cette valeur n’existe pas encore, la méthode ajoute une paire à la carte, avec id comme clé et un objet-bouton de item1 comme valeur. En conséquence, le texte du premier bouton est appliqué avec succès.

L’appel à button2, qui a également id = R.id.button, vérifie la valeur de la carte pour cette clé, trouve notre première vue (le bouton du premier élément), et la remplit avec la valeur du deuxième bouton. Comme résultat le premier bouton change de texte deux fois, le second pas une seule fois

Solution du problème

Au début, vous pouvez utiliser un id différent pour chaque vue. Mais si cela n’est pas utile, vous pouvez revenir à findViewById:

Exécutons l’application et voyons le résultat:

Maintenant cela fonctionne correctement !

Conclusion

Les nouvelles fonctionnalités du langage donnent un lof ot utile, mais vous devez comprendre comment il fonctionne pour éviter les problèmes.

Merci d’avoir lu cet article ! J’espère qu’il vous sera utile

.

Laisser un commentaire