Liaison de vue Fait partie d'Android Jetpack.

La liaison de vue est une fonctionnalité qui facilite l'écriture de code qui interagit avec les vues. Une fois la liaison de vue activée dans un module, elle génère une classe de liaison pour chaque fichier de mise en page XML présent dans ce module. Une instance d'une classe de liaison contient des références directes à toutes les vues qui ont un ID dans la mise en page correspondante.

Dans la plupart des cas, la liaison de vue remplace findViewById.

Configurer

La liaison de vue est activée module par module. Pour activer la liaison de vue dans un module, définissez l'option de compilation viewBinding sur true dans le fichier build.gradle au niveau du module, comme illustré dans l'exemple suivant:

Groovy

android {
    ...
    buildFeatures {
        viewBinding true
    }
}

Kotlin

android {
    ...
    buildFeatures {
        viewBinding = true
    }
}

Si vous souhaitez qu'un fichier de mise en page soit ignoré lors de la génération de classes de liaison, ajoutez l'attribut tools:viewBindingIgnore="true" à la vue racine de ce fichier:

<LinearLayout
        ...
        tools:viewBindingIgnore="true" >
    ...
</LinearLayout>

Utilisation

Si la liaison de vue est activée pour un module, une classe de liaison est générée pour chaque fichier de mise en page XML contenu dans le module. Chaque classe de liaison contient des références à la vue racine et à toutes les vues qui ont un ID. Le nom de la classe de liaison est généré en convertissant le nom du fichier XML en casse Pascal et en ajoutant le mot "Binding" à la fin.

Prenons l'exemple d'un fichier de mise en page appelé result_profile.xml contenant les éléments suivants:

<LinearLayout ... >
    <TextView android:id="@+id/name" />
    <ImageView android:cropToPadding="true" />
    <Button android:id="@+id/button"
        android:background="@drawable/rounded_button" />
</LinearLayout>

La classe de liaison générée est appelée ResultProfileBinding. Cette classe comporte deux champs: un TextView nommé name et un Button nommé button. ImageView dans la mise en page n'a pas d'ID. Il n'y a donc pas de référence à celui-ci dans la classe de liaison.

Chaque classe de liaison inclut également une méthode getRoot(), qui fournit une référence directe pour la vue racine du fichier de mise en page correspondant. Dans cet exemple, la méthode getRoot() de la classe ResultProfileBinding renvoie la vue racine LinearLayout.

Les sections suivantes illustrent l'utilisation des classes de liaison générées dans les activités et les fragments.

Utiliser la liaison de vue dans les activités

Pour configurer une instance de la classe de liaison à utiliser avec une activité, procédez comme suit dans la méthode onCreate() de l'activité:

  1. Appelez la méthode statique inflate() incluse dans la classe de liaison générée. Cette action crée une instance de la classe de liaison pour l'activité à utiliser.
  2. Obtenez une référence à la vue racine en appelant la méthode getRoot() ou en utilisant la syntaxe des propriétés Kotlin.
  3. Transmettez la vue racine à setContentView() pour qu'elle soit active à l'écran.

Ces étapes sont présentées dans l'exemple suivant :

Kotlin

private lateinit var binding: ResultProfileBinding

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ResultProfileBinding.inflate(layoutInflater)
    val view = binding.root
    setContentView(view)
}

Java

private ResultProfileBinding binding;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    binding = ResultProfileBinding.inflate(getLayoutInflater());
    View view = binding.getRoot();
    setContentView(view);
}

Vous pouvez maintenant utiliser l'instance de la classe de liaison pour référencer l'une des vues:

Kotlin

binding.name.text = viewModel.name
binding.button.setOnClickListener { viewModel.userClicked() }

Java

binding.name.setText(viewModel.getName());
binding.button.setOnClickListener(new View.OnClickListener() {
    viewModel.userClicked()
});

Utiliser la liaison de vue dans des fragments

Pour configurer une instance de la classe de liaison à utiliser avec un fragment, procédez comme suit dans la méthode onCreateView() du fragment:

  1. Appelez la méthode statique inflate() incluse dans la classe de liaison générée. Cette action crée une instance de la classe de liaison que le fragment doit utiliser.
  2. Obtenez une référence à la vue racine en appelant la méthode getRoot() ou en utilisant la syntaxe des propriétés Kotlin.
  3. Renvoyez la vue racine à partir de la méthode onCreateView() pour en faire la vue active à l'écran.

Kotlin

private var _binding: ResultProfileBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!

override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    _binding = ResultProfileBinding.inflate(inflater, container, false)
    val view = binding.root
    return view
}

override fun onDestroyView() {
    super.onDestroyView()
    _binding = null
}

Java

private ResultProfileBinding binding;

@Override
public View onCreateView (LayoutInflater inflater,
                          ViewGroup container,
                          Bundle savedInstanceState) {
    binding = ResultProfileBinding.inflate(inflater, container, false);
    View view = binding.getRoot();
    return view;
}

@Override
public void onDestroyView() {
    super.onDestroyView();
    binding = null;
}

Vous pouvez maintenant utiliser l'instance de la classe de liaison pour référencer l'une des vues:

Kotlin

binding.name.text = viewModel.name
binding.button.setOnClickListener { viewModel.userClicked() }

Java

binding.name.setText(viewModel.getName());
binding.button.setOnClickListener(new View.OnClickListener() {
    viewModel.userClicked()
});

Fournir des indications pour différentes configurations

Lorsque vous déclarez des vues pour plusieurs configurations, il peut parfois être judicieux d'utiliser un type de vue différent en fonction de la mise en page. L'extrait de code suivant en donne un exemple:

# in res/layout/example.xml

<TextView android:id="@+id/user_bio" />

# in res/layout-land/example.xml

<EditText android:id="@+id/user_bio" />

Dans ce cas, vous pouvez vous attendre à ce que la classe générée expose un champ userBio de type TextView, car TextView est la classe de base commune. En raison de limites techniques, le générateur de code de liaison de vue ne peut pas déterminer cela et génère un champ View à la place. Cela nécessite de caster le champ ultérieurement avec binding.userBio as TextView.

Pour contourner cette limitation, la liaison de vue accepte un attribut tools:viewBindingType, ce qui vous permet d'indiquer au compilateur le type à utiliser dans le code généré. Dans l'exemple précédent, vous pouvez utiliser cet attribut pour que le compilateur génère le champ en tant que TextView:

# in res/layout/example.xml (unchanged)

<TextView android:id="@+id/user_bio" />

# in res/layout-land/example.xml

<EditText android:id="@+id/user_bio" tools:viewBindingType="TextView" />

Dans un autre exemple, supposons que vous ayez deux mises en page, l'une contenant un élément BottomNavigationView et l'autre contenant un élément NavigationRailView. Les deux classes étendent NavigationBarView, qui contient la plupart des détails de l'implémentation. Si votre code n'a pas besoin de savoir exactement quelle sous-classe est présente dans la mise en page actuelle, vous pouvez utiliser tools:viewBindingType pour définir le type généré sur NavigationBarView dans les deux mises en page:

# in res/layout/navigation_example.xml

<BottomNavigationView android:id="@+id/navigation" tools:viewBindingType="NavigationBarView" />

# in res/layout-w720/navigation_example.xml

<NavigationRailView android:id="@+id/navigation" tools:viewBindingType="NavigationBarView" />

La liaison de vue ne peut pas valider la valeur de cet attribut lors de la génération du code. Pour éviter les erreurs au moment de la compilation et d'exécution, la valeur doit remplir les conditions suivantes:

  • La valeur doit être une classe qui hérite de android.view.View.
  • La valeur doit être une super-classe du tag sur lequel elle est placée. Par exemple, les valeurs suivantes ne fonctionnent pas:

      <TextView tools:viewBindingType="ImageView" /> <!-- ImageView is not related to TextView. -->
      <TextView tools:viewBindingType="Button" /> <!-- Button is not a superclass of TextView. -->
    
  • Le dernier type doit être résolu de manière cohérente dans toutes les configurations.

Différences par rapport à findViewById

La liaison de vue présente des avantages importants par rapport à l'utilisation de findViewById:

  • Sécurité nulle:étant donné que la liaison de vue crée des références directes aux vues, il n'y a aucun risque d'exception de pointeur nul en raison d'un ID de vue non valide. En outre, lorsqu'une vue n'est présente que dans certaines configurations d'une mise en page, le champ contenant sa référence dans la classe de liaison est marqué par @Nullable.
  • Sûreté du typage:les champs de chaque classe de liaison ont des types correspondant aux vues auxquelles ils font référence dans le fichier XML. Cela signifie qu'il n'y a aucun risque d'exception de conversion de classe.

Ces différences signifient des incompatibilités entre votre mise en page et votre code. Par conséquent, la compilation échoue au moment de la compilation plutôt qu'au moment de l'exécution.

Comparaison avec la liaison de données

La liaison de vue et la liaison de données génèrent toutes deux des classes de liaison que vous pouvez utiliser pour référencer directement des vues. Cependant, la liaison de vue est destinée à gérer des cas d'utilisation plus simples et offre les avantages suivants par rapport à la liaison de données:

  • Compilation plus rapide:la liaison de vue ne nécessite aucun traitement d'annotation, ce qui accélère la compilation.
  • Facilité d'utilisation:la liaison de vue ne nécessite pas de fichiers de mise en page XML spécialement tagués. Il est donc plus rapide de l'adopter dans vos applications. Une fois que vous avez activé la liaison de vue dans un module, elle s'applique automatiquement à toutes les mises en page de ce module.

D'autre part, la liaison de vue présente les limites suivantes par rapport à la liaison de données:

Compte tenu de ces considérations, dans certains cas, il est préférable d'utiliser à la fois la liaison de vue et la liaison de données dans un projet. Vous pouvez utiliser la liaison de données dans les mises en page qui nécessitent des fonctionnalités avancées, et la liaison de vue dans les mises en page qui ne le font pas.

Ressources supplémentaires

Pour en savoir plus sur la liaison de vue, consultez les ressources supplémentaires suivantes:

Exemples

Blogs

Vidéos