Comment utiliser la liaison de données et Kotlin dans Android

La plupart du temps, lorsque l’on développe une vue au sein d’un projet mobile, celle-ci a besoin d’afficher des données personnalisées et de réagir aux données entrées par l’utilisateur. Une bonne pratique consiste à séparer de la vue les données et les actions à utiliser pour que le tout ne soit pas trop fortement lié en cas de modification de la logique (principe de séparation des couches). Un modèle couramment utilisé est le modèle MVVM (Model, View, ViewModel) dans lequel le ViewModel contient toutes ces fameuses informations dont vont dépendre nos vues. Il faut cependant trouver le moyen le plus efficace de relier nos différentes couches : c’est ce que nous allons voir aujourd’hui.
En tant que développeur Xamarin – et plus particulièrement Xamarin.Forms- nous sommes habitués à pouvoir utiliser le « ViewBinding » proposé par le framework afin de réduire le travail de liaison et pouvoir faire le lien de manière déclarative directement dans la vue.
Ce ViewBinding propose plusieurs fonctionnalités telles que :
- Les expressions déclaratives: pour pouvoir affiner le binding directement dans la vue.
- Les Converters : afin de convertir une donnée de la source en un type ou une forme adaptée à notre vue, telle que la conversion d’une chaine de caractères représentant une URL en une image exploitable par notre vue par exemple.
- La gestion des évènements.
Très pratique, le ViewBinding est au cœur du développement des applications mobile en Xamarin.Forms. Il est donc tout naturel, au moment de se lancer dans un projet Android natif, de se demander s’il existe un ou plusieurs équivalents et comment les utiliser.
Android propose deux types de binding différents :
- le View Binding
- le Data Binding.
Examinons chacun d’entre eux plus en détails.
Présentation du ViewBinding sur Android
Au premier abord, le ViewBinding sur Android nous offre la possibilité d’éviter tous les appels fastidieux au classique findViewbyId(id) en concaténant toutes les vues identifiées en un seul objet directement utilisable :
- Il permet d’éviter les variables nulles et les erreurs de typages car il récupère directement les vues à la génération, sans risque de ne pas retrouver l’ID passée en paramètre via le classique findViewById(id) ou d’erreur de notre part.
- Il a l’avantage d’être simple d’utilisation, comme nous allons voir par la suite, et d’être rapide à la compilation car il ne nécessite pas d’annotations processeurs supplémentaires.
- Il ne permet cependant pas d’utiliser la liaison de données de manière déclarative: cette dernière devra toujours se faire via les activités/fragments/autres.
- Il est très semblable Butterknife, une ancienne librairie très populaire au sein de la communauté Android.
Présentation du DataBinding sur Android
Le DataBinding permet également de lier notre layout à des classes de binding mais possède plusieurs fonctionnalités supplémentaires comme :
- La liaison déclarative, au sein du layout, de la donnée liée avec la vue ;
- L’utilisation d’expressions au sein de ces liaisons afin de paramétrer le binding ;
- L’utilisation d’adapters, que l’on peut voir comme un équivalent des Converters côté Xamarin.Forms évoqués plus haut ;
- La gestion des évènements ;
- La reliure bidirectionnelle afin que la donnée puisse être mise à jour en temps réel, soit par manipulation au sein de la vue soit au sein du code métier ;
- Une compatibilité avec les LiveData afin d’avoir un rafraîchissement automatique des valeurs utilisées.
Ses fonctionnalités sont bien plus proches de la façon de lier les données utilisées en Xamarin.Forms grâce au ViewBinding, que le « ViewBinding » d’Android vu plus haut.
Mise en pratique de la liaison de données
Initialisation
ViewBinding
Pour utiliser le ViewBinding, il faut d’abord activer sa configuration dans le fichier gradle.build :
A partir du moment où cette fonctionnalité est activée, à la prochaine compilation, toutes les classes de binding seront générées. Ainsi, si nous avons un fichier activity_main.xml, cela génèrera un fichier ActivityMainBinding.
Utilisons un layout simple pour la suite :
La classe ActivityMainBinding aura donc la propriété name de type TextView et la propriété button de type Button. Toute vue qui ne possède pas d’ID dans le layout sera ignorée au moment de la génération.
DataBinding
De la même façon que pour le Viewbinding au sein du build.gradle :
A noter : contrairement au ViewBinding qui génère automatiquement toutes les classes de binding dès le moment où la fonctionnalité est activée, il va ici falloir rajouter des tags manuellement dans les layout que l’on veut générer en englobant notre layout comme ceci :
Les variables à l’intérieur du tag <data> seront tous les objets utilisables par la suite via nos expressions pour lier nos vues aux données.
Comme précédemment avec le ViewBinding, si le fichier se nomme activity_main.xml, cela produit une classe ActivityMainBinding qui contiendra un champ de type User nommé « user » qu’il faudra renseigner au moment de l’utilisation.
Comment utiliser les classes générées ?
Explorons deux cas : les Activités et les Fragments
Activités
Tout se fait dans la méthode onCreate(), comme le montrent les exemples ci-dessous.
ViewBinding
- On utilise le inflate() afin de récupérer le binding.
- On accède à la racine contenant nos propriétés via binding.root.
- On lie l’activité à la vue récupérée via setContentView(view).
Il est ensuite possible d’utiliser nos vues de la façon suivante :
DataBinding
- On utilise le DataBindingUtil.setContentView afin de récupérer le binding en passant en paramètre le layout utilisé (ici R.layout.activity_main)
- On renseigne le ou les objet(s) utilisé(s) pour le binding, ici binding.user.
- C’est tout ! Grâce à l’objet user, il sera à présent capable de lier toutes ses propriétés aux vues l’utilisant dans notre layout.
Fragments
De manière similaire, on utilise la méthode onCreateView() afin d’inflate notre classe de binding.
ViewBinding
Encore une fois, il est possible d’utiliser nos vues de la façon suivante :
DataBinding
On utilisera la méthode DataBindingUtil.inflate au sein du onCreateView() de la façon suivante :
DataBinding ou ViewBiding : lequel utiliser ?
Il semble facile de se dire que puisque le DataBinding permet de faire tout ce que fait le ViewBinding en apportant bon nombre de fonctionnalités supplémentaires, il suffit d’utiliser le DataBinding tout le temps.
Je voudrais néanmoins attirer votre attention sur certains points :
- Le ViewBinding a un temps de compilation bien plus rapide que le DataBinding, du fait qu’il n’utilise pas d’annotations de processeur supplémentaires pour fonctionner.
- Le DataBinding alourdit les vues d’une surcouche via les tags <layout> et <data>, ce qui constitue un frein potentiel pour certains développeurs pour la lisibilité, et ajoute un temps supplémentaire d’intégration en cas de projet déjà existant.
- Les deux peuvent co-exister au sein d’un même projet: il est donc parfaitement possible d’utiliser le DataBinding uniquement pour les vues nécessitant des fonctionnalités supplémentaires qu’il propose.
J’espère que cet article vous aura permis d’y voir plus clair sur les différentes méthodes actuelles pour utiliser les liaisons de données et vous aidera à déterminer plus sereinement laquelle choisir.
Si vous souhaitez approfondir le sujet je vous invite à consulter les documentations officielles :