Créer des mises en page XML pour Android

1. Avant de commencer

Dans cet atelier de programmation, vous créerez la mise en page d'une application basique de calcul de pourboire. Vous obtiendrez comme résultat une interface utilisateur fonctionnelle. Toutefois, l'application ne calculera pas encore le pourboire. Les prochains ateliers de programmation vous aideront à donner à l'application une apparence plus professionnelle.

Conditions préalables

  • Vous savez créer et exécuter une application Android à partir d'un modèle dans Android Studio.

Points abordés

  • Lire et écrire des mises en page XML sous Android
  • Créer la mise en page d'un formulaire simple pour accueillir le texte des utilisateurs et leurs choix

Objectifs de l'atelier

  • Interface utilisateur d'une application de calcul de pourboire pour Android

Ce dont vous avez besoin

2. Démarrer le projet

Découvrez la calculatrice de pourboires sur Google : https://www.google.com/search?q=tip+calculator

18da3c120daa0759.png

Dans ce parcours, vous créerez une version simple d'une calculatrice de pourboire, qui prendre la forme d'une application Android.

Les développeurs travaillent souvent de cette manière : ils préparent une version simple et partiellement fonctionnelle de l'application (sans se concentrer sur l'aspect esthétique), puis la rendent entièrement fonctionnelle et plus agréable à l'œil par la suite.

Voici ce à quoi ressemblera votre application de calcul de pourboire à la fin de cet atelier de programmation :

bcc5260318477c14.png

Vous utiliserez les éléments d'interface utilisateur suivants, fournis par Android :

  • EditText : permet de saisir et de modifier du texte.
  • TextView : permet d'afficher du texte tel qu'une question sur la qualité du service et le montant du pourboire.
  • RadioButton : case d'option qui peut être sélectionnée pour chaque option de pourboire.
  • RadioGroup : permet de regrouper les options de cases d'option.
  • Switch : bouton d'activation ou de désactivation permettant de choisir d'arrondir le pourboire ou non.

Créer un projet "Activité vide"

  1. Pour commencer, créez un projet Kotlin dans Android Studio à l'aide du modèle Activité vide.
  2. Donnez le nom "Tip Time" à votre application et appliquez-lui un niveau d'API minimal de 19 (KitKat). Le nom du package est com.example.tiptime.

4f7619e9faff20e9.png

  1. Cliquez sur Terminer pour créer l'application.

3. Lire et comprendre le format XML

Au lieu d'utiliser l'éditeur de mise en page que vous connaissez déjà, vous modifierez le code XML qui décrit l'interface utilisateur, afin de créer la mise en page de l'application. En tant que développeur Android, il est important que vous vous familiarisiez avec la création et la modification de mises en page de l'interface utilisateur à l'aide du code XML.

Vous examinerez et modifierez le fichier XML qui définit la mise en page de l'interface utilisateur pour cette application. XML est l'acronyme de eXtensible Markup Language. Ce langage permet de décrire des données à l'aide d'un document texte. Comme le format XML est extensible et très flexible, il est utilisé pour de nombreuses tâches, y compris pour définir la mise en page de l'interface utilisateur des applications Android. Comme nous l'avons vu précédemment dans d'autres ateliers de programmation, d'autres ressources telles que les chaînes correspondant à votre application sont également définies dans un fichier XML appelé strings.xml.

L'interface utilisateur d'une application Android repose sur une hiérarchie de composants (widgets) et sur la mise en page de ces composants à l'écran. Notez que ces mises en page sont elles-mêmes des composants de l'interface utilisateur.

C'est à vous de déterminer la hiérarchie des éléments de l'interface utilisateur à l'écran. Par exemple, un élément ConstraintLayout (parent) peut contenir Buttons, TextViews, ImageViews ou d'autres vues (enfants). N'oubliez pas que ConstraintLayout est une sous-classe de ViewGroup. Cela vous permet de positionner ou de dimensionner les vues enfants de manière flexible.

74c7c563d18fffd4.png

Hiérarchie des composants d'une application Android

32df120272b2331d.png

Chaque élément d'interface utilisateur est représenté par un élément XML dans le fichier XML. Chaque élément commence et se termine par une balise, et chaque balise commence par un < et se termine par un >. Tout comme vous pouvez définir des attributs au niveau des éléments d'interface utilisateur à l'aide de l'éditeur de mise en page, les éléments XML peuvent également avoir des attributs. Pour simplifier, le code XML des éléments d'interface utilisateur ci-dessus peut se présenter comme suit :

<ConstraintLayout>
    <TextView
        text="Hello World!">
    </TextView>
</ConstraintLayout>

8dea708333aebabe.png

Prenons un exemple concret.

  1. Ouvrez activity_main.xml (res > layout > activity_main.xml).
  2. Vous remarquerez peut-être que l'application affiche un élément TextView avec "Hello World!" dans un composant ConstraintLayout, comme vous l'avez vu dans les projets précédents créés à partir de ce modèle.

4fbdb64c02d62e73.png

  1. Les options associées aux vues Code, Split (Diviser) et Design (Conception) se trouvent en haut à droite de l'éditeur de mise en page.
  2. Sélectionnez la vue Code.

6203bec920791bcc.png

Voici à quoi ressemble le code XML dans activity_main.xml :

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Cet exemple est beaucoup plus complexe que l'exemple simplifié, mais Android Studio s'efforce de rendre le code XML plus lisible, tout comme dans le code Kotlin.

  1. Notez la mise en retrait. Android Studio effectue cette opération automatiquement pour indiquer la hiérarchie des éléments. TextView est en retrait, car il est contenu dans ConstraintLayout. ConstraintLayout est le parent, et TextView l'enfant. Les attributs de chaque élément sont mis en retrait pour indiquer qu'ils font partie de cet élément.
  2. Notez le code couleur : certains éléments sont en bleu, d'autres en vert, etc. Les parties similaires du fichier sont dessinées dans la même couleur pour vous aider à faire le lien entre elles. Vous remarquerez en particulier qu'Android Studio dessine le début et la fin des balises d'éléments de la même couleur. Notez que les couleurs utilisées dans l'atelier de programmation peuvent ne pas correspondre à celles affichées dans Android Studio.

Balises, éléments et attributs XML

Voici une version simplifiée de l'élément TextView, qui vous permet de vous concentrer sur des points essentiels :

<TextView
    android:text="Hello World!"
/>

La ligne comportant <TextView correspond au début de la balise, et la ligne avec /> correspond à la fin de la balise. La ligne comportant android:text="Hello World!" est un attribut de la balise. Elle représente le texte qui sera affiché par TextView. Ces trois lignes sont un raccourci couramment utilisé, appelé balise d'élément vide. La signification serait la même si vous aviez écrit ce code avec une balise de début et une balise de fin distinctes, comme suit :

<TextView
    android:text="Hello World!"
></TextView>

Avec une balise d'élément vide, il est également courant d'écrire sur le moins de lignes possible et de combiner la fin de la balise avec la ligne précédente. Il est donc possible qu'une balise d'élément vide s'affiche sur deux lignes (voire sur une seule ligne en l'absence d'attribut) :

<!-- with attributes, two lines -->
<TextView
    android:text="Hello World!" />

L'élément ConstraintLayout est écrit avec des balises de début et de fin distinctes, car il doit pouvoir contenir d'autres éléments. Voici une version simplifiée de l'élément ConstraintLayout contenant l'élément TextView :

<androidx.constraintlayout.widget.ConstraintLayout>
    <TextView
        android:text="Hello World!" />
</androidx.constraintlayout.widget.ConstraintLayout>

Si vous souhaitez ajouter un autre élément View en tant qu'enfant de ConstraintLayout, par exemple un élément Button sous TextView, insérez-le après la fin de la balise TextView /> et avant la balise de fin de ConstraintLayout, comme suit :

<androidx.constraintlayout.widget.ConstraintLayout>
    <TextView
        android:text="Hello World!" />
    <Button
        android:text="Calculate" />
</androidx.constraintlayout.widget.ConstraintLayout>

En savoir plus sur le format XML pour les mises en page

  1. Examinez la balise de ConstraintLayout et notez qu'elle indique androidx.constraintlayout.widget.ConstraintLayout au lieu de simplement ConstraintLayout comme TextView. Cela est dû au fait que ConstraintLayout fait partie d'Android Jetpack, qui contient des bibliothèques de code offrant des fonctionnalités supplémentaires par rapport à la plate-forme Android principale. Jetpack propose des fonctionnalités utiles que vous pouvez exploiter pour créer des applications plus facilement. Vous pouvez déterminer que ce composant d'interface utilisateur provient de Jetpack, car il commence par "androidx".
  2. Vous avez peut-être remarqué les lignes commençant par xmlns:, puis android, app et tools.
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"

xmlns est l'acronyme de "XML namespace" (espace de noms XML). Chaque ligne définit un schéma, ou vocabulaire, pour les attributs liés à ces mots. L'espace de noms android:, par exemple, marque les attributs définis par le système Android. Tous les attributs du fichier XML de mise en page commencent par l'un de ces espaces de noms.

  1. Les espaces blancs entre les éléments XML ne changent pas la signification pour les ordinateurs, mais ils peuvent faciliter la lecture du code XML pour les utilisateurs.

Pour une meilleure lisibilité, Android Studio ajoute automatiquement un espace blanc et un retrait. Vous découvrirez ultérieurement comment faire en sorte qu'Android Studio s'assure que votre code XML respecte les conventions de style de codage.

  1. Vous pouvez ajouter des commentaires au code XML, comme vous le feriez avec du code Kotlin. Commencez avec <!-- et terminez par -->.
<!-- this is a comment in XML -->

<!-- this is a
multi-line
Comment.
And another
Multi-line comment -->
  1. Notez la première ligne du fichier :
<?xml version="1.0" encoding="utf-8"?>

Elle indique que le fichier est au format XML,. Toutefois, les fichiers XML ne fournissent pas tous cette information.

4. Créer la mise en page au format XML

  1. Toujours dans activity_main.xml, passez à la vue Diviser pour afficher le code XML à côté de l'éditeur de conception. L'éditeur de conception vous permet d'afficher un aperçu de la mise en page de votre interface utilisateur.

a03bcf5beacb4b45.png

  1. Vous pouvez choisir la vue qui vous convient, mais pour cet atelier de programmation, optez pour la vue Split (Diviser) afin de voir à la fois le code XML que vous modifiez et les modifications apportées dans l'éditeur de conception.
  2. Cliquez sur différentes lignes, par exemple en dessous de ConstraintLayout, puis en dessous de TextView, et notez que la vue correspondante est sélectionnée dans l'éditeur de conception. L'inverse fonctionne également : par exemple, si vous cliquez sur TextView dans l'éditeur de conception, le code XML correspondant est mis en surbrillance.

1abc54a646c39f66.png

Supprimer l'élément TextView

  1. Comme vous n'avez pas besoin de l'élément TextView à ce stade, supprimez-le. Veillez à le supprimer entièrement, en commençant par <TextView et en terminant par />.
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Hello World!"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

Tout ce qu'il vous reste dans le fichier est le composant ConstraintLayout :

<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

</androidx.constraintlayout.widget.ConstraintLayout>
  1. Ajoutez une marge intérieure de 16 dp à ConstraintLayout afin que l'interface utilisateur ne soit pas complètement collée au bord de l'écran.

La marge intérieure est semblable aux marges standards, mais elle ajoute de l'espace à l'intérieur de ConstraintLayout, au lieu d'ajouter de l'espace à l'extérieur.

<androidx.constraintlayout.widget.ConstraintLayout
    ...
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    tools:context=".MainActivity">

Ajouter un champ de texte permettant d'indiquer le coût du service

Au cours de cette étape, vous ajouterez un élément d'interface utilisateur pour permettre à l'utilisateur de saisir le coût du service dans l'application. Vous utiliserez l'élément EditText, qui permet à l'utilisateur de saisir ou de modifier du texte dans une application.

7746dedb0d79923f.png

  1. Consultez la documentation EditText et examinez l'exemple XML.
  2. Recherchez un espace entre les balises d'ouverture et de fermeture de ConstraintLayout.
  3. Copiez et collez le code XML issu de la documentation dans cet espace de la mise en page dans Android Studio.

Votre fichier de mise en page devrait se présenter comme suit :

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/plain_text_input"
        android:layout_height="wrap_content"
        android:layout_width="match_parent"
        android:inputType="text"/>

</androidx.constraintlayout.widget.ConstraintLayout>

Tout n'est peut-être pas encore très clair, mais les étapes suivantes vous permettront de comprendre ce qu'il se passe.

  1. Notez qu'EditText est souligné en rouge.
  2. Passez la souris au-dessus. Un message (que vous devriez déjà avoir vu dans les précédents ateliers de programmation) indique alors que la vue n'est pas fixée. Rappelez-vous que les enfants d'un élément ConstraintLayout ont besoin de contraintes afin que la mise en page sache comment les organiser.

40c17058bd6786f.png

  1. Ajoutez ces contraintes à EditText pour ancrer la vue dans l'angle supérieur gauche du parent.
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"

Si vous écrivez en français ou dans une autre langue s'écrivant de gauche à droite, le bord de départ est à gauche. Toutefois, certaines langues telles que l'arabe sont écrites de droite à gauche. Le point de départ est donc à droite. C'est pourquoi la contrainte utilise le paramètre "start" (départ) pour qu'elle puisse fonctionner avec n'importe quelle langue. De même, les contraintes utilisent "end" (fin) plutôt que "right" (à droite).

Une fois les nouvelles contraintes ajoutées, l'élément EditText se présentera comme suit :

<EditText
    android:id="@+id/plain_text_input"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    android:inputType="text"/>

Vérifier les attributs EditText

Vérifiez tous les attributs EditText que vous avez collés pour vous assurer qu'ils fonctionnent correctement dans votre application.

  1. Recherchez l'attribut id, qui est défini sur @+id/plain_text_input.
  2. Remplacez l'attribut id par un nom plus approprié, @+id/cost_of_service.
  1. Examinez l'attribut layout_height. Sa valeur indique wrap_content, ce qui signifie que la hauteur équivaut à celle de son contenu. Cela ne pose pas de problème, car il n'y aura qu'une seule ligne de texte.
  2. Examinez l'attribut layout_width. Il indique match_parent, mais vous ne pouvez pas définir match_parent sur un enfant de ConstraintLayout. En outre, le champ de texte n'a pas besoin d'être aussi large. Définissez-le sur une largeur fixe de 160dp, ce qui devrait laisser suffisamment de place à l'utilisateur pour saisir le coût du service.

1f82a5e86ae94fd2.png

  1. Notez l'attribut inputType, qui est nouveau. Sa valeur indique "text", ce qui signifie que l'utilisateur peut saisir n'importe quel caractère de texte dans le champ à l'écran (caractères alphabétiques, symboles, etc.).
android:inputType="text"

En revanche, vous souhaitez que l'utilisateur ne puisse saisir que des nombres dans le champ EditText, qui est destiné à une valeur monétaire.

  1. Effacez le mot text, mais conservez les guillemets.
  2. Commencez à saisir number à la place. Après avoir saisi "n", Android Studio affiche une liste des suggestions possibles contenant ou commençant par la lettre "n".

99b04cbd21e74693.gif

  1. Sélectionnez numberDecimal, ce qui permet uniquement les chiffres décimaux.
android:inputType="numberDecimal"

Pour consulter les autres types d'entrées possibles, accédez à la section Spécifier le type de mode de saisie dans la documentation destinée aux développeurs.

Il reste une modification à effectuer pour indiquer à l'utilisateur ce qu'il doit saisir dans ce champ.

  1. Ajoutez un attribut hint à EditText et décrivez le type d'information que l'utilisateur doit ajouter dans ce champ.
android:hint="Cost of Service"

L'éditeur de conception se met à jour en conséquence.

824454d2a316efb1.png

  1. Exécutez votre application dans l'émulateur. Elle devrait se présenter comme suit :

c9d413de53b0853d.png

Bravo ! L'application ne permet pas encore de faire grand-chose, mais vous avez commencé sur de bonnes bases et vous vous êtes exercé à modifier le code XML. Le code XML de la mise en page devrait se présenter comme suit :

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/cost_of_service"
        android:layout_width="160dp"
        android:layout_height="wrap_content"
        android:hint="Cost of Service"
        android:inputType="numberDecimal"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Ajouter une question sur la qualité du service

Au cours de cette étape, vous ajouterez un élément TextView pour la question "Comment avez-vous trouvé le service ?". Essayez de saisir directement la commande, sans avoir recours au copier-coller. Les suggestions d'Android Studio devraient vous aider.

  1. Après la fermeture de la balise EditText, />, ajoutez une nouvelle ligne et commencez à saisir <TextView.
  2. Sélectionnez TextView parmi les suggestions. Android Studio ajoutera automatiquement les attributs layout_width et layout_height pour TextView.
  3. Dans les deux cas, choisissez wrap_content, car seul l'élément TextView doit être aussi grand que le contenu textuel. fee18cc43df85294.png
  4. Ajoutez l'attribut text avec la question "How was the service?".
<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="How was the service?"
  1. Fermez la balise avec />.
  2. Dans l'éditeur de conception, notez que TextView et EditText se chevauchent.

ac09d5cae6ae2455.png

Pour éviter ce comportement, vous allez ajouter des contraintes à l'élément TextView. Réfléchissez aux contraintes dont vous avez besoin. Où l'élément TextView doit-il être positionné horizontalement et verticalement ? Vous pouvez consulter la capture d'écran de l'application pour vous aider à répondre à cette question.

bcc5260318477c14.png

Verticalement, vous souhaitez que TextView se trouve sous le champ de saisie du coût du service. Horizontalement, vous voulez que TextView commence au même niveau que le parent.

  1. Ajoutez une contrainte horizontale à TextView pour que son bord de départ correspond à celui du parent.
app:layout_constraintStart_toStartOf="parent"
  1. Ajoutez une contrainte verticale à TextView pour que le bord supérieur de l'élément TextView se trouve sous le bord inférieur de l'élément View indiquant le coût du service.
app:layout_constraintTop_toBottomOf="@id/cost_of_service"

Notez qu'il n'y a pas de signe plus dans @id/cost_of_service, car l'ID est déjà défini.

3822136f7ed815f2.png

L'apparence n'est pas idéale, mais ce n'est pas une priorité pour l'instant. À ce stade, assurez-vous simplement que tous les éléments nécessaires s'affichent à l'écran et que la fonctionnalité est opérationnelle. Vous peaufinerez l'apparence dans les ateliers de programmation suivants.

  1. Ajoutez un ID de ressource au niveau de TextView. Vous devrez renvoyer à cette vue ultérieurement lorsque que vous ajouterez des vues et que vous y appliquerez des contraintes.
android:id="@+id/service_question"

À ce stade, le code XML devrait se présenter comme suit :

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/cost_of_service"
        android:hint="Cost of Service"
        android:layout_height="wrap_content"
        android:layout_width="160dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:inputType="numberDecimal"/>

    <TextView
        android:id="@+id/service_question"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="How was the service?"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/cost_of_service"/>

</androidx.constraintlayout.widget.ConstraintLayout>

5. Ajouter les options de pourboire

Vous allez maintenant ajouter des cases d'option pour les différentes options de pourboire que l'utilisateur peut sélectionner.

Trois options s'offrent à vous :

  • Amazing (Excellent) : 20 %
  • Good (Satisfaisant) : 18 %
  • Okay (Standard) : 15 %

Si vous ne savez pas comment procéder, vous pouvez effectuer une recherche Google. C'est ce que font souvent les développeurs lorsqu'ils sont bloqués.

  1. Recherchez radio button android sur Google. Le premier résultat est un guide du site pour les développeurs Android expliquant comment utiliser les cases d'option. C'est exactement ce qu'il vous faut !

f5f1c6778ae7a5d.png

  1. Parcourez le Guide des cases d'option.

En lisant la description, vous confirmez que vous pouvez utiliser un élément d'interface utilisateur RadioButton dans la mise en page pour chaque case d'option dont vous avez besoin. Vous découvrez aussi que vous devez regrouper les cases d'option dans un élément RadioGroup, car l'utilisateur ne pourra sélectionner qu'une seule option à la fois.

Un extrait de code XML semble être adapté à vos besoins. Lisez-le pour découvrir en quoi RadioGroup est la vue parent et en quoi RadioButtons est une vue enfant.

  1. Revenez à la mise en page dans Android Studio pour ajouter RadioGroup et RadioButton à l'application.
  2. Après l'élément TextView, mais toujours dans le composant ConstraintLayout, commencez à saisir <RadioGroup. Android Studio fournit des suggestions utiles pour vous aider à écrire le code XML. aee75ba409dc51aa.png
  3. Définissez les valeurs layout_width et layout_height de l'élément RadioGroup sur wrap_content.
  4. Ajoutez un ID de ressource défini sur @+id/tip_options.
  5. Fermez la balise de départ avec le signe >.
  6. Android Studio ajoute </RadioGroup>. Comme pour ConstraintLayout, l'élément RadioGroup contient d'autres sous-éléments. Vous pouvez donc le déplacer et lui assigner sa propre ligne. Définition de layout_width et layout_height sur wrap_content
  7. Appliquez la contrainte RadioGroup sous la question sur la qualité du service (verticalement) et au début du parent (horizontalement).
  8. Définissez l'attribut android:orientation sur vertical. Si vous souhaitez afficher les éléments RadioButtons d'affilée, définissez l'orientation sur horizontal.

Le code XML de RadioGroup doit se présenter comme suit :

<RadioGroup
    android:id="@+id/tip_options"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@id/service_question">

</RadioGroup>

Ajouter des cases d'option

  1. Après le dernier attribut de RadioGroup, mais avant la balise de fin </RadioGroup>, ajoutez un élément RadioButton.
<RadioGroup
    android:id="@+id/tip_options"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@id/service_question">

    <!-- add RadioButtons here -->

</RadioGroup>
  1. Définissez layout_width et layout_height sur wrap_content.
  2. Attribuez l'ID de ressource @+id/option_twenty_percent à RadioButton.
  3. Définissez le texte sur Amazing (20%).
  4. Fermez la balise avec />.
<RadioGroup
   android:id="@+id/tip_options"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   app:layout_constraintTop_toBottomOf="@id/service_question"
   app:layout_constraintStart_toStartOf="parent"
   android:orientation="vertical">

   <RadioButton
       android:id="@+id/option_twenty_percent"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="Amazing (20%)" />

</RadioGroup>

53cb416b368e9612.png

Maintenant que vous avez ajouté un élément RadioButton, voyons si vous pouvez modifier le code XML pour ajouter deux autres cases pour les options Good (18%) et Okay (15%).

Voici ce à quoi ressemble le code XML pour RadioGroup et RadioButtons :

<RadioGroup
   android:id="@+id/tip_options"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   app:layout_constraintTop_toBottomOf="@id/service_question"
   app:layout_constraintStart_toStartOf="parent"
   android:orientation="vertical">

   <RadioButton
       android:id="@+id/option_twenty_percent"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="Amazing (20%)" />

   <RadioButton
       android:id="@+id/option_eighteen_percent"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="Good (18%)" />

   <RadioButton
       android:id="@+id/option_fifteen_percent"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="Okay (15%)" />

</RadioGroup>

bab25b6a35d4ce52.png

Ajouter une sélection par défaut

Aucune option de pourboire n'est actuellement sélectionnée. Nous vous conseillons de choisir une case comme option par défaut.

Un attribut de l'élément RadioGroup permet de déterminer quel bouton doit être coché initialement. Il s'appelle checkedButton et doit être défini sur l'ID de ressource de la case d'option souhaitée.

  1. Dans RadioGroup, définissez l'attribut android:checkedButton sur @id/option_twenty_percent.
<RadioGroup
   android:id="@+id/tip_options"
   android:checkedButton="@id/option_twenty_percent"
   ...

Dans l'éditeur de conception, vous remarquerez que la mise en page a été mise à jour. L'option de pourboire de 20 % est maintenant sélectionnée par défaut. Notre calculatrice de pourboire commence à prendre forme.

c412e7f16590cd33.png

Voici ce à quoi ressemble le code XML jusqu'à présent :

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/cost_of_service"
        android:hint="Cost of Service"
        android:layout_height="wrap_content"
        android:layout_width="160dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:inputType="numberDecimal"/>

    <TextView
        android:id="@+id/service_question"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="How was the service?"
        app:layout_constraintTop_toBottomOf="@id/cost_of_service"
        app:layout_constraintStart_toStartOf="parent" />

    <RadioGroup
        android:id="@+id/tip_options"
        android:checkedButton="@id/option_twenty_percent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintTop_toBottomOf="@id/service_question"
        app:layout_constraintStart_toStartOf="parent"
        android:orientation="vertical">

        <RadioButton
            android:id="@+id/option_twenty_percent"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Amazing (20%)" />

        <RadioButton
            android:id="@+id/option_eighteen_percent"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Good (18%)" />

        <RadioButton
            android:id="@+id/option_fifteen_percent"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Okay (15%)" />
    </RadioGroup>
</androidx.constraintlayout.widget.ConstraintLayout>

6. Finaliser la mise en page

Voici la dernière ligne droite de la mise en page. Vous ajouterez des éléments Switch, Button et TextView pour afficher le montant du pourboire.

bcc5260318477c14.png

Ajouter un bouton bascule pour arrondir le pourboire

Vous allez maintenant utiliser un widget Switch pour permettre à l'utilisateur de sélectionner "oui" ou "non" pour arrondir le pourboire.

Vous souhaitez que Switch soit aussi large que le parent. Vous pouvez donc définir sa largeur sur match_parent. Comme indiqué précédemment, vous ne pouvez pas définir de match_parent au niveau des éléments d'interface utilisateur d'un composant ConstraintLayout. À la place, vous devez appliquer des contraintes aux bords de début et de fin de la vue, puis définir la largeur sur 0dp. La définition de la largeur sur 0dp indique au système de ne pas calculer la largeur et de simplement respecter les contraintes spécifiées au niveau de la vue.

  1. Ajoutez un élément Switch après le code XML de l'élément RadioGroup.
  2. Comme indiqué ci-dessus, définissez layout_width sur 0dp.
  3. Définissez layout_height sur wrap_content. La vue Switch sera ainsi aussi grande que son contenu.
  4. Définissez l'attribut id sur @+id/round_up_switch.
  5. Définissez l'attribut text sur Round up tip?. Il sera utilisé comme libellé pour l'élément Switch.
  6. Appliquez une contrainte au bord de début de Switch pour qu'il s'aligne sur le bord de début de tip_options, et une contrainte à la fin par rapport à la fin du parent.
  7. Appliquez une contrainte à la partie supérieure de Switch pour qu'elle se trouve sous tip_options.
  8. Fermez la balise avec />.

Il serait utile d'activer le connecteur par défaut. Pour ce faire, utilisez l'attribut android:checked, où les valeurs possibles sont true (activé) ou false (désactivé).

  1. Définissez l'attribut android:checked sur true.

En résumé, le code XML de l'élément Switch se présente comme suit :

<Switch
    android:id="@+id/round_up_switch"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:checked="true"
    android:text="Round up tip?"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="@id/tip_options"
    app:layout_constraintTop_toBottomOf="@id/tip_options" />

d374fab984650296.png

Ajouter le bouton de calcul

Vous allez maintenant ajouter un élément Button pour que l'utilisateur puisse demander le calcul du pourboire. Vous souhaitez que le bouton soit aussi large que le parent. Dès lors, les contraintes et la largeur horizontales sont les mêmes que pour l'élément Switch.

  1. Ajoutez un élément Button après Switch.
  2. Définissez la largeur sur 0dp, comme vous l'avez fait pour Switch.
  3. Définissez la hauteur sur wrap_content.
  4. Attribuez-lui l'ID de ressource @+id/calculate_button, avec le texte "Calculate".
  5. Ajoutez une contrainte au bord supérieur de Button pour qu'il se trouve sous le bord inférieur de l'élément Switch Round up tip? (Arrondir le pourboire).
  6. Appliquez une contrainte au bord de début pour qu'il s'aligne sur le bord de début du parent, et une contrainte au bord de fin par rapport au bord de fin du parent.
  7. Fermez la balise avec />.

Voici à quoi ressemble le code XML de l'élément Button Calculate (Calculer) :

<Button
   android:id="@+id/calculate_button"
   android:layout_width="0dp"
   android:layout_height="wrap_content"
   android:text="Calculate"
   app:layout_constraintTop_toBottomOf="@id/round_up_switch"
   app:layout_constraintStart_toStartOf="parent"
   app:layout_constraintEnd_toEndOf="parent" />

5338cf87c61d15c9.png

Ajouter un résultat de pourboire

La mise en page est presque terminée. Au cours de cette étape, vous allez ajouter un élément TextView pour le résultat du pourboire, le placer sous le bouton Calculate (Calculer) et l'aligner avec la fin plutôt que le début, comme les autres éléments de l'interface utilisateur.

  1. Ajoutez un élément TextView avec un ID de ressource nommé tip_result et le texte Tip Amount.
  2. Appliquez une contrainte au bord de fin de TextView par rapport au bord de fin du parent.
  3. Appliquez des contraintes au bord supérieur par rapport au inférieur du bouton Calculate (Calculer).
<TextView
    android:id="@+id/tip_result"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintTop_toBottomOf="@id/calculate_button"
    android:text="Tip Amount" />

9644bcdabbd8d7d1.png

  1. Exécutez l'application. Elle devrait ressembler à cette capture d'écran.

e4ed552fa9fbe4ce.png

Bien joué, surtout si c'est la première fois que vous modifiez du code XML !

Notez que l'application peut différer de la capture d'écran, car les modèles peuvent avoir changé dans une version ultérieure d'Android Studio. Le bouton Calculate (Calculer) n'est encore associé à aucune action. Toutefois, vous pouvez saisir le coût, sélectionner le pourcentage du pourboire et activer ou désactiver l'option permettant d'arrondir le pourboire ou non. Le bouton Calculate (Calculer) sera configuré et activé dans l'atelier de programmation suivant. Veillez donc à ne pas manquer cette étape.

7. Adopter les bonnes pratiques de codage

Extraire les chaînes

Vous avez peut-être remarqué des avertissements concernant les chaînes codées en dur. Comme nous l'avons vu lors des précédents ateliers de programmation, l'extraction des chaînes dans un fichier de ressources facilite la traduction de votre application dans d'autres langues et la réutilisation des chaînes. Parcourez activity_main.xml et extrayez toutes les ressources de chaîne.

  1. Cliquez sur une chaîne. Passez la souris sur l'icône représentant une ampoule jaune, puis cliquez sur le triangle situé à côté. Sélectionnez Extraire la ressource de chaîne. Les noms par défaut des ressources de chaîne suffisent. Si vous le souhaitez, vous pouvez utiliser amazing_service, good_service et ok_service pour que les noms soient plus descriptifs.

Vérifiez maintenant les ressources de chaîne que vous venez d'ajouter.

  1. Si la fenêtre Projet ne s'affiche pas, cliquez sur l'onglet Projet situé à gauche de la fenêtre.
  2. Ouvrez app > res > values > string.xml pour afficher toutes les ressources de chaîne de l'interface utilisateur.
<resources>
    <string name="app_name">Tip Time</string>
    <string name="cost_of_service">Cost of Service</string>
    <string name="how_was_the_service">How was the service?</string>
    <string name="amazing_service">Amazing (20%)</string>
    <string name="good_service">Good (18%)</string>
    <string name="ok_service">Okay (15%)</string>
    <string name="round_up_tip">Round up tip?</string>
    <string name="calculate">Calculate</string>
    <string name="tip_amount">Tip Amount</string>
</resources>

Remettre en forme le fichier XML

Android Studio offre divers outils pour nettoyer le code et vous assurer qu'il respecte les conventions de codage recommandées.

  1. Dans activity_main.xml, sélectionnez Modifier > Tout sélectionner.
  2. Sélectionnez Code > Remettre en forme le code.

Cette action permet d'assurer la cohérence des retraits et de réorganiser le code XML des éléments d'interface utilisateur afin de regrouper des éléments, tels que tous les attributs android: d'un seul et même élément.

8. Code de la solution

bcc5260318477c14.png

res/layout/activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="16dp"
    tools:context=".MainActivity">

    <EditText
        android:id="@+id/cost_of_service"
        android:layout_width="160dp"
        android:layout_height="wrap_content"
        android:hint="@string/cost_of_service"
        android:inputType="numberDecimal"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/service_question"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/how_was_the_service"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/cost_of_service" />

    <RadioGroup
        android:id="@+id/tip_options"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:checkedButton="@id/option_twenty_percent"
        android:orientation="vertical"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/service_question">

        <RadioButton
            android:id="@+id/option_twenty_percent"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/amazing_service" />

        <RadioButton
            android:id="@+id/option_eighteen_percent"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/good_service" />

        <RadioButton
            android:id="@+id/option_fifteen_percent"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/ok_service" />
    </RadioGroup>

    <Switch
        android:id="@+id/round_up_switch"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:checked="true"
        android:text="@string/round_up_tip"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="@id/tip_options"
        app:layout_constraintTop_toBottomOf="@id/tip_options" />

    <Button
        android:id="@+id/calculate_button"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:text="@string/calculate"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@id/round_up_switch" />

    <TextView
        android:id="@+id/tip_result"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/tip_amount"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toBottomOf="@id/calculate_button" />
</androidx.constraintlayout.widget.ConstraintLayout>

res/values/strings.xml

<resources>
   <string name="app_name">Tip Time</string>
   <string name="cost_of_service">Cost of Service</string>
   <string name="how_was_the_service">How was the service?</string>
   <string name="amazing_service">Amazing (20%)</string>
   <string name="good_service">Good (18%)</string>
   <string name="ok_service">Okay (15%)</string>
   <string name="round_up_tip">Round up tip?</string>
   <string name="calculate">Calculate</string>
   <string name="tip_amount">Tip Amount</string>
</resources>

9. Résumé

  • Le format XML (Extensible Markup Language) permet d'organiser le texte à l'aide de balises, d'éléments et d'attributs.
  • Vous pouvez utiliser le format XML pour la mise en page d'une application Android.
  • Vous pouvez utiliser EditText pour permettre à l'utilisateur de saisir ou de modifier du texte.
  • Un élément EditText peut inclure un indice pour indiquer à l'utilisateur l'objectif de ce champ.
  • Vous pouvez spécifier l'attribut android:inputType pour limiter le type de texte que l'utilisateur peut saisir dans un champ EditText.
  • Vous pouvez créer une liste d'options exclusives avec des éléments RadioButtons, regroupés dans un élément RadioGroup.
  • Un élément RadioGroup peut être vertical ou horizontal, et vous pouvez spécifier quel élément RadioButton doit être coché initialement.
  • Vous pouvez utiliser un élément Switch pour permettre à l'utilisateur de basculer entre deux options.
  • Vous pouvez ajouter un libellé à un élément Switch sans utiliser d'élément TextView distinct.
  • Chaque enfant d'un composant ConstraintLayout doit avoir des contraintes verticales et horizontales.
  • Vous pouvez utiliser des contraintes de début (start) et de fin (end) pour gérer les langues qui se lisent de gauche à droite et celles qui se lisent de droite à gauche.
  • Les noms des attributs de contrainte se présentent sous la forme layout_constraint<Source>_to<Target>Of.
  • Pour définir un élément View aussi large que le composant ConstraintLayout qu'elle contient, appliquez des contraintes au début et à la fin par rapport au début et à la fin du parent, et définissez la largeur sur 0 dp.

10. En savoir plus

Vous trouverez ci-dessous des liens vers d'autres documents sur les sujets abordés. Toute la documentation spécifique au développement Android se trouve sur developer.android.com. N'oubliez pas que vous pouvez aussi effectuer une recherche Google si vous rencontrez un problème.

11. Pour s'entraîner

Action à effectuer :

  • Créez une autre application de calculatrice, par exemple un convertisseur d'onces en millilitres, de tasses en grammes, etc. De quels champs aurez-vous besoin ?