Classes de liaison générées

La bibliothèque Data Binding génère des classes de liaison que vous pouvez utiliser pour accéder aux variables et aux vues de la mise en page. Cette documentation explique comment créer et personnaliser les classes de liaison générées.

La classe de liaison générée associe les variables de mise en page aux vues de la mise en page. Vous pouvez personnaliser le nom et le package de la liaison. Toutes les classes de liaison générées héritent de la classe ViewDataBinding.

Une classe de liaison est générée pour chaque fichier de mise en page. Par défaut, le nom de la classe est le nom du fichier de mise en page converti en casse Pascal, avec le suffixe Binding ajouté. Ainsi, par exemple, si le nom de fichier de la mise en page est activity_main.xml, la classe générée correspondante est ActivityMainBinding. Cette classe contient toutes les liaisons entre les propriétés de mise en page et les vues de la mise en page, et sait comment attribuer des valeurs aux expressions de liaison.

Créer un objet de liaison

L'objet de liaison est créé immédiatement après le gonflement de la mise en page pour garantir que la hiérarchie des vues n'est pas modifiée avant d'être liée aux vues avec des expressions dans la mise en page. La méthode la plus courante pour lier l'objet à une mise en page consiste à utiliser les méthodes statiques sur la classe de liaison. Vous pouvez gonfler la hiérarchie des vues et lui associer l'objet en utilisant la méthode inflate() de la classe de liaison, comme illustré dans l'exemple suivant:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    val binding: MyLayoutBinding = MyLayoutBinding.inflate(layoutInflater)

    setContentView(binding.root)
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    MyLayoutBinding binding = MyLayoutBinding.inflate(getLayoutInflater());

    setContentView(binding.root);
}

Il existe une autre version de la méthode inflate() qui accepte un objet ViewGroup en plus de l'objet LayoutInflater , comme illustré dans l'exemple suivant:

Kotlin

val binding: MyLayoutBinding = MyLayoutBinding.inflate(getLayoutInflater(), viewGroup, false)

Java

MyLayoutBinding binding = MyLayoutBinding.inflate(getLayoutInflater(), viewGroup, false);

Si la mise en page est gonflée à l'aide d'un autre mécanisme, vous pouvez la lier séparément, comme suit:

Kotlin

val binding: MyLayoutBinding = MyLayoutBinding.bind(viewRoot)

Java

MyLayoutBinding binding = MyLayoutBinding.bind(viewRoot);

Parfois, vous ne connaissez pas le type de liaison à l'avance. Dans ce cas, vous pouvez créer la liaison à l'aide de la classe DataBindingUtil, comme illustré dans l'extrait de code suivant:

Kotlin

val viewRoot = LayoutInflater.from(this).inflate(layoutId, parent, attachToParent)
val binding: ViewDataBinding? = DataBindingUtil.bind(viewRoot)

Java

View viewRoot = LayoutInflater.from(this).inflate(layoutId, parent, attachToParent);
ViewDataBinding binding = DataBindingUtil.bind(viewRoot);

Si vous utilisez des éléments de liaison de données dans un adaptateur Fragment, ListView ou RecyclerView, vous pouvez utiliser les méthodes inflate() des classes de liaison ou la classe DataBindingUtil, comme illustré dans l'exemple de code suivant:

Kotlin

val listItemBinding = ListItemBinding.inflate(layoutInflater, viewGroup, false)
// or
val listItemBinding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false)

Java

ListItemBinding binding = ListItemBinding.inflate(layoutInflater, viewGroup, false);
// or
ListItemBinding binding = DataBindingUtil.inflate(layoutInflater, R.layout.list_item, viewGroup, false);

Vues avec ID

La bibliothèque Data Binding crée un champ immuable dans la classe de liaison pour chaque vue disposant d'un ID dans la mise en page. Par exemple, la bibliothèque Data Binding crée les champs firstName et lastName de type TextView à partir de la mise en page suivante:

<layout xmlns:android="http://schemas.android.com/apk/res/android">
   <data>
       <variable name="user" type="com.example.User"/>
   </data>
   <LinearLayout
       android:orientation="vertical"
       android:layout_width="match_parent"
       android:layout_height="match_parent">
       <TextView android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="@{user.firstName}"
   android:id="@+id/firstName"/>
       <TextView android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="@{user.lastName}"
  android:id="@+id/lastName"/>
   </LinearLayout>
</layout>

La bibliothèque extrait les vues, y compris les ID, de la hiérarchie des vues en une seule fois. Ce mécanisme peut être plus rapide que d'appeler la méthode findViewById() pour chaque vue de la mise en page.

Les ID ne sont pas aussi nécessaires qu'ils ne le sont sans liaison de données, mais dans certains cas, l'accès aux vues est nécessaire à partir du code.

Variables

La bibliothèque Data Binding génère des méthodes d'accesseur pour chaque variable déclarée dans la mise en page. Par exemple, la mise en page suivante génère des méthodes setter et getter dans la classe de liaison pour les variables user, image et note:

<data>
   <import type="android.graphics.drawable.Drawable"/>
   <variable name="user" type="com.example.User"/>
   <variable name="image" type="Drawable"/>
   <variable name="note" type="String"/>
</data>

ViewStubs

Contrairement aux vues normales, les objets ViewStub commencent comme des vues invisibles. Lorsqu'elles sont visibles ou explicitement gonflées, elles se remplacent dans la mise en page en gonflant une autre mise en page.

Étant donné que ViewStub disparaît de la hiérarchie des vues, la vue de l'objet de liaison doit également disparaître pour pouvoir être revendiquée par la récupération de mémoire. Comme les affichages sont finaux, un objet ViewStubProxy remplace le ViewStub dans la classe de liaison générée, ce qui vous donne accès au ViewStub lorsqu'il existe et à la hiérarchie des vues gonflée en cas de gonflement du ViewStub.

Lorsque vous gonflez une autre mise en page, une liaison doit être établie pour la nouvelle mise en page. Par conséquent, ViewStubProxy doit écouter ViewStub OnInflateListener et établir la liaison si nécessaire. Étant donné qu'un seul écouteur ne peut exister à la fois, ViewStubProxy vous permet de définir un OnInflateListener, qu'il appelle une fois la liaison établie.

Liaison immédiate

Lorsqu'une variable ou un objet observable change, la modification de la liaison est programmée avant le frame suivant. Toutefois, dans certains cas, la liaison doit être exécutée immédiatement. Pour forcer l'exécution, utilisez la méthode executePendingBindings().

Variables dynamiques

Il peut arriver que la classe de liaison spécifique soit inconnue. Par exemple, un RecyclerView.Adapter fonctionnant sur des mises en page arbitraires ne connaît pas la classe de liaison spécifique. Il doit attribuer la valeur de liaison lors de l'appel de la méthode onBindViewHolder().

Dans l'exemple suivant, toutes les mises en page associées par RecyclerView comportent une variable item. L'objet BindingHolder comporte une méthode getBinding() qui renvoie la classe de base ViewDataBinding.

Kotlin

override fun onBindViewHolder(holder: BindingHolder, position: Int) {
    item: T = items.get(position)
    holder.binding.setVariable(BR.item, item);
    holder.binding.executePendingBindings();
}

Java

public void onBindViewHolder(BindingHolder holder, int position) {
    final T item = items.get(position);
    holder.getBinding().setVariable(BR.item, item);
    holder.getBinding().executePendingBindings();
}

Thread d'arrière-plan

Vous pouvez modifier votre modèle de données dans un thread en arrière-plan, tant qu'il ne s'agit pas d'une collection. La liaison de données localise chaque variable ou champ lors de l'évaluation afin d'éviter tout problème de simultanéité.

Noms des classes de liaison personnalisées

Par défaut, une classe de liaison est générée en fonction du nom du fichier de mise en page, commençant par une lettre majuscule, supprimant les traits de soulignement ( _), la lettre suivante en majuscule et le mot Binding en suffixe. Par exemple, le fichier de mise en page contact_item.xml génère la classe ContactItemBinding. La classe est placée dans un package databinding sous le package de module. Par exemple, si le package du module est com.example.my.app, la classe de liaison est placée dans le package com.example.my.app.databinding.

Les classes de liaison peuvent être renommées ou placées dans différents packages en ajustant l'attribut class de l'élément data. Par exemple, la mise en page suivante génère la classe de liaison ContactItem dans le package databinding du module actuel:

<data class="ContactItem">
    ...
</data>

Vous pouvez générer la classe de liaison dans un package différent en ajoutant un point au nom de la classe. L'exemple suivant génère la classe de liaison dans le package de module:

<data class=".ContactItem">
    ...
</data>

Vous pouvez également utiliser le nom de package complet à l'endroit où vous souhaitez que la classe de liaison soit générée. L'exemple suivant crée la classe de liaison ContactItem dans le package com.example:

<data class="com.example.ContactItem">
    ...
</data>

Ressources supplémentaires

Pour en savoir plus sur la liaison de données, consultez les ressources supplémentaires suivantes.