Introduction de la liaison de données

 La bibliothèque de liaison de données permet d’écrire des dispositions déclaratives qui minimisent le code collant nécessaire pour lier les éléments View aux sources de données sous-jacentes en générant ce code pour vous au moment de la compilation.

 

Nous allons vous présenter les principes fondamentaux, mais nous vous recommandons de vous reporter à la documentation du développeur Android pour obtenir plus de détails à l'adresse developer.android.com / topic / libraries / data-binding.

 Activation de la liaison de données 

La liaison de données est une bibliothèque facultative. Par conséquent, avant de pouvoir en tirer parti, vous devez l'activer dans le fichier build.gradle de votre module d'application:

 android {

  [... Existing Android Node ...]   dataBinding.enabled = true }

dependencies {

  [... Existing dependencies element ...]

  implementation 'com.android.support:support-v4:27.1.1' }

Une fois activé, vous pouvez appliquer la liaison de données à n’importe quelle présentation en encapsulant les éléments d’un fichier de présentation dans un nouvel élément <layout>, comme indiqué dans le Listing 5-6:

 LISTING 5-6 : Activation de la liaison de données dans une présentation

 < ?xml version="1.0" encoding="utf-8"? >

<layout

  xmlns:android="http://schemas.android.com/apk/res/android">

  <LinearLayout

    android:layout_width="match_parent"     android:layout_height="wrap_content"     android:orientation="vertical">

    <TextView

      android:id="@+id/user_name"       android:layout_width="match_parent"       android:layout_height="wrap_content" />

    <TextView

      android:id="@+id/email"       android:layout_width="match_parent"       android:layout_height="wrap_content" />

  </LinearLayout>

< /layout >

Cela force la liaison de données à générer une classe de liaison en fonction du nom du fichier de présentation modifié. Par exemple, pour une présentation définie dans profile_activity.xml, la classe Binding générée serait nommée ProfileActivityBinding.

 Vous créez une instance d'une classe Binding à l'aide de DataBindingUtil et utilisez sa méthode setContentView à la place de l'objet setContentView de l'activité:

ProfileActivityBinding binding =

    DataBindingUtil.setContentView(this, R.layout.profile_activity);

Pour gonfler la vue associée à un élément Fragment ou Recycler View, utilisez la méthode de gonflage de la classe Binding:

 ProfileActivityBinding binding =

    ProfileActivityBinding.inflate(layoutInflater, viewGroup, false);

Vous pouvez également créer une classe de liaison de données à partir d'une vue existante:

 ProfileActivityBinding binding =

    (ProfileActivityBinding) DataBindingUtil.bind(view);

La classe Binding appelle automatiquement findViewById sur chaque vue avec un ID dans la présentation associée. Ainsi, au lieu de conserver une référence à chaque vue de votre présentation ou de devoir appeler findViewById vous-même, vous pouvez référencer la vue via la classe de liaison:

 binding.userName.setText("professionalandroid"); binding.email.setText("Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser.");

 Variables dans la liaison de données 

La puissance de cette liaison de données entièrement opérationnelle réside dans sa capacité à simplifier le processus de liaison dynamique de vos données sous-jacentes à la présentation. Pour ce faire, vous ajoutez un élément <data> et déclarez des variables pouvant être utilisées dans la présentation à l'aide de la syntaxe @ {name.classvariable}, comme indiqué dans le Listing 5-7.

 LISTING 5-7: Application de variables de liaison de données dans une présentation

 < ?xml version="1.0" encoding="utf-8"? >

<layout

  xmlns:android="http://schemas.android.com/apk/res/android">

  <data>

    <variable name="user" type="com.professionalandroid.databinding.User" />

  </data>

  <LinearLayout

    android:layout_width="match_parent"     android:layout_height="wrap_content"     android:orientation="vertical">

    <TextView

      android:layout_width="match_parent"       android:layout_height="wrap_content"       android:text="@{user.userName}" />

    <TextView

      android:layout_width="match_parent"       android:layout_height="wrap_content"       android:text="@{user.email}" />

  </LinearLayout>

< /layout >

En déclarant une variable nommée utilisateur, de la classe User, notre classe Binding générera une méthode setUser.

L'appel de cette méthode définira toutes les propriétés référençant cette classe à l'aide de la syntaxe @ {}. La liaison de données recherche les variables publiques, les méthodes de lecture du style get <Variable> ou is <Variable> (par exemple, getEmail ou isValid), ou le nom exact de la méthode lors de la résolution d'expressions:

 User user = new User("professionalandroid", "Cette adresse e-mail est protégée contre les robots spammeurs. Vous devez activer le JavaScript pour la visualiser."); binding.setUser(user);

 Cela vous permet de conserver toute la logique spécifique à View dans le fichier de présentation lui-même, tandis que votre code ne peut se concentrer que sur la fourniture des données appropriées à la classe Binding.

 Vous remarquerez que les attributs android: id ont été supprimés dans l'exemple précédent, car la liaison de données ne nécessite pas d'identifiant pour évaluer les expressions de variable.

Outre la spécification de variables, vous pouvez utiliser presque toute la syntaxe du langage Java au sein de ces expressions. Par exemple, vous pouvez utiliser l'opérateur null-coalescing ?? pour raccourcir les expressions ternaires simples:

 android:text='@{user.email ?? "No email"}'

 Par défaut, toutes les variables que vous appliquez sont appliquées après la prochaine mise à jour de l'image. Cela peut provoquer un scintillement visible lorsqu’il est utilisé dans des vues défilables telles que la vue Recycler. Pour éviter cela, appelez executePendingBindings après avoir défini vos variables, afin que la liaison soit effectuée immédiatement:

 User user = userList.get(position);

binding.setUser(user); binding.executePendingBindings();

 Liaison de données pour l'application Earthquake Viewer

 La liaison de données nous permet de simplifier RecyclerView.Adapter de Earthquake Viewer en liant chaque séisme à la présentation de chaque rangée: 1. Mettez à jour le fichier build.gradle pour activer la liaison de données:

android {

  [... Existing android element ...]   dataBinding.enabled = true }

dependencies {

  [... Existing dependencies element ...]

  implementation 'com.android.support:support-v4:27.1.1' }

  1. Mettez à jour la ressource de présentation list_item_earthquake.xml pour tirer parti de la liaison de données:

 < ?xml version="1.0" encoding="utf-8"? >

< layout

  xmlns:android="http://schemas.android.com/apk/res/android"   xmlns:app="http://schemas.android.com/apk/res-auto">

  <data>

    <variable name="timeformat" type="java.text.DateFormat" />

    <variable name="magnitudeformat" type="java.text.NumberFormat" />

    <variable name="earthquake"

      type="com.professionalandroid.apps.earthquake.Earthquake" />

  </data>

  <android.support.constraint.ConstraintLayout     android:layout_width="match_parent"     android:layout_height="wrap_content"

    android:paddingLeft="@dimen/activity_vertical_margin"     android:paddingRight="@dimen/activity_vertical_margin">

    <TextView

      android:id="@+id/magnitude"       android:layout_width="wrap_content"       android:layout_height="0dp"       android:gravity="center_vertical"       app:layout_constraintRight_toRightOf="parent"       app:layout_constraintTop_toTopOf="parent"       app:layout_constraintBottom_toBottomOf="parent"       android:textAppearance="?attr/textAppearanceListItem"

      android:text="@{magnitudeformat.format(earthquake.magnitude)}"/>

    <TextView

      android:id="@+id/date"       android:layout_width="0dp"       android:layout_height="wrap_content"       android:layout_marginTop="@dimen/text_margin"       app:layout_constraintLeft_toLeftOf="parent"       app:layout_constraintTop_toTopOf="parent"       app:layout_constraintRight_toLeftOf="@id/magnitude"       android:text="@{timeformat.format(earthquake.date)}"/>

    <TextView

      android:layout_width="0dp"       android:layout_height="wrap_content"       android:layout_marginBottom="@dimen/text_margin"       app:layout_constraintLeft_toLeftOf="parent"       app:layout_constraintBottom_toBottomOf="parent"       app:layout_constraintRight_toLeftOf="@id/magnitude"       app:layout_constraintTop_toBottomOf="@id/date"       android:text="@{earthquake.details}"/>

  </android.support.constraint.ConstraintLayout>

< /layout >

  1. Générez la classe Binding en reconstruisant le projet. Vous pouvez le déclencher manuellement via l'élément de menu Construire Construire un projet.
  2. Mettez à jour le EarthquakeRecyclerViewAdapter.ViewHolder pour recevoir la classe Binding en tant que saisissez et initialisez une fois les paramètres de format de temps et de magnitude:

public static class ViewHolder extends RecyclerView.ViewHolder {   public final ListItemEarthquakeBinding binding;

  public ViewHolder(ListItemEarthquakeBinding binding) {

    super(binding.getRoot());     this.binding = binding;     binding.setTimeformat(TIME_FORMAT);

    binding.setMagnitudeformat(MAGNITUDE_FORMAT);

  }

}

  1. Mettez à jour EarthquakeRecyclerViewAdapter pour créer la classe Binding dans onCreateViewHolder et simplifiez onBindViewHolder:

 @Override

public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {   ListItemEarthquakeBinding binding = ListItemEarthquakeBinding.inflate(

    LayoutInflater.from(parent.getContext()), parent, false);

  return new ViewHolder(binding);

}

@Override

public void onBindViewHolder(ViewHolder holder, int position) {

  Earthquake earthquake = mEarthquakes.get(position);

  holder.binding.setEarthquake(earthquake);   holder.binding.executePendingBindings(); }