Utilisation de modèles pour créer des interfaces utilisateur indépendantes du périphérique

 Une caractéristique déterminante des classes de mise en page est leur capacité à évoluer et à s'adapter à une gamme de tailles d'écran, de résolutions et d'orientations.

La variété des appareils Android est un élément essentiel du succès de la plate-forme, mais pour nous, développeurs d’applications, elle présente un défi pour la conception d’UI offrant la meilleure expérience possible aux utilisateurs, quel que soit l’appareil Android qu’ils possèdent.

 Utilisation de Disposition Linéaire

 La disposition linéaire est l’une des classes de disposition les plus simples. Il vous permet de créer des interfaces utilisateur simples (ou des éléments d'interface utilisateur) qui alignent une séquence de vues enfant verticalement ou horizontalement.

La simplicité de la disposition linéaire facilite son utilisation, mais limite sa flexibilité. Dans la plupart des cas, vous utiliserez des dispositions linéaires pour construire des éléments d'interface utilisateur qui seront imbriqués dans d'autres dispositions, telles que les dispositions relatives ou de contrainte.

Le Listing 5-1 montre deux dispositions linéaires imbriquées, à savoir une disposition horizontale de deux boutons de taille égale dans une disposition verticale qui place les boutons au-dessus d’une vue Recycler.

 LISTING 5-1 : Utilisation de Linear Layout

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

< LinearLayout

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

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

  <LinearLayout

    android:layout_width="match_parent"     android:layout_height="wrap_content"     android:layout_marginLeft="5dp"     android:layout_marginRight="5dp"     android:layout_marginTop="5dp"     android:orientation="horizontal">

    <Button

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

      android:layout_weight="1"

      android:text="@string/cancel_button_text" />

    <Button

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

      android:layout_weight="1"

      android:text="@string/ok_button_text" />

  </LinearLayout>

  <android.support.v7.widget.RecyclerView     android:layout_width="match_parent"     android:layout_height="match_parent"     android:paddingBottom="5dp"     android:clipToPadding="false" /> < /LinearLayout >

 Si vous créez des modèles d’imbrication de plus en plus complexes de dispositions linéaires, vous serez probablement mieux servi en utilisant un gestionnaire de présentation plus souple, tel que la disposition par contrainte.

 Utilisation de Disposition relative

 La disposition relative offre une grande flexibilité pour vos présentations, vous permettant de définir la position de chaque élément dans la présentation en termes de parent et des autres vues.

Le Listing 5-2 modifie la présentation décrite dans le Listing 5-1 pour déplacer les boutons sous la vue Recycler.

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

< RelativeLayout

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

  android:layout_width="match_parent"   android:layout_height="match_parent">

  <LinearLayout

    android:id="@+id/button_bar"     android:layout_alignParentBottom="true"     android:layout_width="match_parent"     android:layout_height="wrap_content"     android:layout_marginLeft="5dp"     android:layout_marginRight="5dp"     android:layout_marginBottom="5dp"     android:orientation="horizontal">

    <Button

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

      android:layout_weight="1"

      android:text="@string/cancel_button_text" />

    <Button

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

      android:layout_weight="1"

      android:text="@string/ok_button_text" />

  </LinearLayout>

  <android.support.v7.widget.RecyclerView     android:layout_above="@id/button_bar"     android:layout_alignParentLeft="true"     android:layout_width="match_parent"     android:layout_height="match_parent"

    android:paddingTop="5dp"     android:clipToPadding="false" />

< /RelativeLayout >

 Utilisation d'une disposition de contrainte

 La disposition des contraintes offre la plus grande souplesse de tous les gestionnaires de disposition, offrant l'avantage à la fois d'un éditeur de disposition visuel et d'une hiérarchie de vues horizontale sans imbrication illustrée dans les exemples précédents.

Il est disponible dans la bibliothèque de support Android et doit être inclus en tant que dépendance du fichier build.gradle de votre projet:

 dependencies {

  [... Existing dependencies ...]

  implementation 'com.android.support.constraint:constraint-layout:1.1.2' }

 Comme son nom l'indique, la disposition de contrainte positionne ses vues enfants à travers la spécification de contraintes qui définissent la relation entre une vue et des éléments tels que des limites, d'autres vues et des instructions personnalisées.

Bien qu'il soit possible de définir manuellement une disposition de contrainte en XML, il est beaucoup plus simple (et moins sujet aux erreurs) d'utiliser l'éditeur de disposition visuelle. La figure 5-2 illustre l'éditeur de disposition utilisé pour créer la même interface utilisateur que l'exemple précédent, à l'aide d'une disposition de contrainte.

 Le listing 5-3 montre le code XML produit par l'éditeur visuel de la figure 5-2.

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

< android.support.constraint.ConstraintLayout

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

  android:layout_width="match_parent"   android:layout_height="match_parent">

  <Button

    android:id="@+id/cancel_button"     android:layout_width="0dp"     android:layout_height="wrap_content"     android:layout_marginStart="5dp"     android:layout_marginBottom="5dp"     app:layout_constraintStart_toStartOf="parent"     app:layout_constraintEnd_toStartOf="@+id/ok_button"     app:layout_constraintTop_toBottomOf="@+id/recyclerView"     app:layout_constraintBottom_toBottomOf="parent"     android:text="@string/cancel_button_text" />

  <Button

    android:id="@+id/ok_button"     android:layout_width="0dp"     android:layout_height="wrap_content"     android:layout_marginEnd="5dp"     android:layout_marginBottom="5dp"

    app:layout_constraintStart_toEndOf="@id/cancel_button"

    app:layout_constraintEnd_toEndOf="parent"     app:layout_constraintTop_toBottomOf="@id/recyclerView"     app:layout_constraintBottom_toBottomOf="parent"     android:text="@string/ok_button_text" />

  <android.support.v7.widget.RecyclerView     android:id="@+id/recyclerView"     android:layout_width="0dp"     android:layout_height="0dp"

    app:layout_constraintStart_toStartOf="parent"     app:layout_constraintEnd_toEndOf="parent"     app:layout_constraintTop_toTopOf="parent"     app:layout_constraintBottom_toTopOf="@id/ok_button"

    android:paddingTop="5dp"     android:clipToPadding="false" /> < /android.support.constraint.ConstraintLayout >

 Notez en particulier que cette disposition supprime la nécessité d'imbriquer une deuxième disposition dans la disposition de contrainte parent. Le fait d'aplatir notre hiérarchie réduit le nombre de passes de mesure et de présentation requises pour le rendu à l'écran, ce qui le rend plus efficace.