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
- Un ordinateur exécutant la dernière version stable d'Android Studio
- Une connexion Internet pour accéder à la documentation Android pour les développeurs
2. Démarrer le projet
Découvrez la calculatrice de pourboires sur Google : https://www.google.com/search?q=tip+calculator

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 :

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"
- Pour commencer, créez un projet Kotlin dans Android Studio à l'aide du modèle Activité vide.
- 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.

- 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.

Hiérarchie des composants d'une application Android

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>

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

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

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.
- Notez la mise en retrait. Android Studio effectue cette opération automatiquement pour indiquer la hiérarchie des éléments.
TextViewest en retrait, car il est contenu dansConstraintLayout.ConstraintLayoutest le parent, etTextViewl'enfant. Les attributs de chaque élément sont mis en retrait pour indiquer qu'ils font partie de cet élément. - 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
- Examinez la balise de
ConstraintLayoutet notez qu'elle indiqueandroidx.constraintlayout.widget.ConstraintLayoutau lieu de simplementConstraintLayoutcommeTextView. Cela est dû au fait queConstraintLayoutfait 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". - Vous avez peut-être remarqué les lignes commençant par
xmlns:, puisandroid,appettools.
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.
- 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.
- 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 -->
- 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
- 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.

- 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.
- Cliquez sur différentes lignes, par exemple en dessous de
ConstraintLayout, puis en dessous deTextView, et notez que la vue correspondante est sélectionnée dans l'éditeur de conception. L'inverse fonctionne également : par exemple, si vous cliquez surTextViewdans l'éditeur de conception, le code XML correspondant est mis en surbrillance.

Supprimer l'élément TextView
- Comme vous n'avez pas besoin de l'élément
TextViewà ce stade, supprimez-le. Veillez à le supprimer entièrement, en commençant par<TextViewet 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>
- Ajoutez une marge intérieure de 16 dp à
ConstraintLayoutafin 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.

- Consultez la documentation
EditTextet examinez l'exemple XML. - Recherchez un espace entre les balises d'ouverture et de fermeture de
ConstraintLayout. - 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.
- Notez qu'
EditTextest souligné en rouge. - 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
ConstraintLayoutont besoin de contraintes afin que la mise en page sache comment les organiser.

- Ajoutez ces contraintes à
EditTextpour 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.
- Recherchez l'attribut
id, qui est défini sur@+id/plain_text_input. - Remplacez l'attribut
idpar un nom plus approprié,@+id/cost_of_service.
- Examinez l'attribut
layout_height. Sa valeur indiquewrap_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. - Examinez l'attribut
layout_width. Il indiquematch_parent, mais vous ne pouvez pas définirmatch_parentsur un enfant deConstraintLayout. En outre, le champ de texte n'a pas besoin d'être aussi large. Définissez-le sur une largeur fixe de160dp, ce qui devrait laisser suffisamment de place à l'utilisateur pour saisir le coût du service.

- 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.
- Effacez le mot
text, mais conservez les guillemets. - 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".

- 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.
- Ajoutez un attribut
hintàEditTextet 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.

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

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.
- Après la fermeture de la balise
EditText,/>, ajoutez une nouvelle ligne et commencez à saisir<TextView. - Sélectionnez
TextViewparmi les suggestions. Android Studio ajoutera automatiquement les attributslayout_widthetlayout_heightpourTextView. - Dans les deux cas, choisissez
wrap_content, car seul l'élémentTextViewdoit être aussi grand que le contenu textuel.
- Ajoutez l'attribut
textavec la question"How was the service?".
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="How was the service?"
- Fermez la balise avec
/>. - Dans l'éditeur de conception, notez que
TextViewetEditTextse chevauchent.

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.

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.
- Ajoutez une contrainte horizontale à
TextViewpour que son bord de départ correspond à celui du parent.
app:layout_constraintStart_toStartOf="parent"
- Ajoutez une contrainte verticale à
TextViewpour que le bord supérieur de l'élémentTextViewse trouve sous le bord inférieur de l'élémentViewindiquant 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.

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.
- 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.
- Recherchez
radio button androidsur 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 !

- 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.
- Revenez à la mise en page dans Android Studio pour ajouter
RadioGroupetRadioButtonà l'application. - Après l'élément
TextView, mais toujours dans le composantConstraintLayout, commencez à saisir<RadioGroup. Android Studio fournit des suggestions utiles pour vous aider à écrire le code XML.
- Définissez les valeurs
layout_widthetlayout_heightde l'élémentRadioGroupsurwrap_content. - Ajoutez un ID de ressource défini sur
@+id/tip_options. - Fermez la balise de départ avec le signe
>. - Android Studio ajoute
</RadioGroup>. Comme pourConstraintLayout, l'élémentRadioGroupcontient d'autres sous-éléments. Vous pouvez donc le déplacer et lui assigner sa propre ligne.
- Appliquez la contrainte
RadioGroupsous la question sur la qualité du service (verticalement) et au début du parent (horizontalement). - Définissez l'attribut
android:orientationsurvertical. Si vous souhaitez afficher les élémentsRadioButtonsd'affilée, définissez l'orientation surhorizontal.
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
- Après le dernier attribut de
RadioGroup, mais avant la balise de fin</RadioGroup>, ajoutez un élémentRadioButton.
<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>
- Définissez
layout_widthetlayout_heightsurwrap_content. - Attribuez l'ID de ressource
@+id/option_twenty_percentàRadioButton. - Définissez le texte sur
Amazing (20%). - 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>

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>

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.
- Dans
RadioGroup, définissez l'attributandroid:checkedButtonsur@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.

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.

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.
- Ajoutez un élément
Switchaprès le code XML de l'élémentRadioGroup. - Comme indiqué ci-dessus, définissez
layout_widthsur0dp. - Définissez
layout_heightsurwrap_content. La vueSwitchsera ainsi aussi grande que son contenu. - Définissez l'attribut
idsur@+id/round_up_switch. - Définissez l'attribut
textsurRound up tip?. Il sera utilisé comme libellé pour l'élémentSwitch. - Appliquez une contrainte au bord de début de
Switchpour qu'il s'aligne sur le bord de début detip_options, et une contrainte à la fin par rapport à la fin du parent. - Appliquez une contrainte à la partie supérieure de
Switchpour qu'elle se trouve soustip_options. - 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é).
- Définissez l'attribut
android:checkedsurtrue.
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" />

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.
- Ajoutez un élément
ButtonaprèsSwitch. - Définissez la largeur sur
0dp, comme vous l'avez fait pourSwitch. - Définissez la hauteur sur
wrap_content. - Attribuez-lui l'ID de ressource
@+id/calculate_button, avec le texte"Calculate". - Ajoutez une contrainte au bord supérieur de
Buttonpour qu'il se trouve sous le bord inférieur de l'élémentSwitchRound up tip? (Arrondir le pourboire). - 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.
- 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" />

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.
- Ajoutez un élément
TextViewavec un ID de ressource nommétip_resultet le texteTip Amount. - Appliquez une contrainte au bord de fin de
TextViewpar rapport au bord de fin du parent. - 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" />

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

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.
- 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_serviceetok_servicepour que les noms soient plus descriptifs.
Vérifiez maintenant les ressources de chaîne que vous venez d'ajouter.
- Si la fenêtre Projet ne s'affiche pas, cliquez sur l'onglet Projet situé à gauche de la fenêtre.
- 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.
- Dans
activity_main.xml, sélectionnez Modifier > Tout sélectionner. - 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

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
EditTextpour permettre à l'utilisateur de saisir ou de modifier du texte. - Un élément
EditTextpeut inclure un indice pour indiquer à l'utilisateur l'objectif de ce champ. - Vous pouvez spécifier l'attribut
android:inputTypepour limiter le type de texte que l'utilisateur peut saisir dans un champEditText. - Vous pouvez créer une liste d'options exclusives avec des éléments
RadioButtons, regroupés dans un élémentRadioGroup. - Un élément
RadioGrouppeut être vertical ou horizontal, et vous pouvez spécifier quel élémentRadioButtondoit être coché initialement. - Vous pouvez utiliser un élément
Switchpour permettre à l'utilisateur de basculer entre deux options. - Vous pouvez ajouter un libellé à un élément
Switchsans utiliser d'élémentTextViewdistinct. - Chaque enfant d'un composant
ConstraintLayoutdoit 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
Viewaussi large que le composantConstraintLayoutqu'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 ?