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
TextView
avec "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.
TextView
est en retrait, car il est contenu dansConstraintLayout
.ConstraintLayout
est le parent, etTextView
l'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
ConstraintLayout
et notez qu'elle indiqueandroidx.constraintlayout.widget.ConstraintLayout
au lieu de simplementConstraintLayout
commeTextView
. Cela est dû au fait queConstraintLayout
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". - Vous avez peut-être remarqué les lignes commençant par
xmlns:
, puisandroid
,app
ettools
.
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 surTextView
dans 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<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>
- 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.
- Consultez la documentation
EditText
et 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'
EditText
est 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
ConstraintLayout
ont besoin de contraintes afin que la mise en page sache comment les organiser.
- 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.
- Recherchez l'attribut
id
, qui est défini sur@+id/plain_text_input
. - Remplacez l'attribut
id
par 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_parent
sur 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
à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.
- 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
TextView
parmi les suggestions. Android Studio ajoutera automatiquement les attributslayout_width
etlayout_height
pourTextView
. - Dans les deux cas, choisissez
wrap_content
, car seul l'élémentTextView
doit être aussi grand que le contenu textuel. - 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?"
- Fermez la balise avec
/>
. - Dans l'éditeur de conception, notez que
TextView
etEditText
se 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 à
TextView
pour que son bord de départ correspond à celui du parent.
app:layout_constraintStart_toStartOf="parent"
- Ajoutez une contrainte verticale à
TextView
pour que le bord supérieur de l'élémentTextView
se trouve sous le bord inférieur de l'élémentView
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.
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 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 !
- 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
RadioGroup
etRadioButton
à 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_width
etlayout_height
de l'élémentRadioGroup
surwrap_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émentRadioGroup
contient d'autres sous-éléments. Vous pouvez donc le déplacer et lui assigner sa propre ligne. - Appliquez la contrainte
RadioGroup
sous la question sur la qualité du service (verticalement) et au début du parent (horizontalement). - Définissez l'attribut
android:orientation
survertical
. Si vous souhaitez afficher les élémentsRadioButtons
d'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_width
etlayout_height
surwrap_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: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.
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
Switch
après le code XML de l'élémentRadioGroup
. - Comme indiqué ci-dessus, définissez
layout_width
sur0dp
. - Définissez
layout_height
surwrap_content
. La vueSwitch
sera ainsi aussi grande que son contenu. - Définissez l'attribut
id
sur@+id/round_up_switch
. - Définissez l'attribut
text
surRound up tip?
. Il sera utilisé comme libellé pour l'élémentSwitch
. - Appliquez une contrainte au bord de début de
Switch
pour 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
Switch
pour 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:checked
surtrue
.
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
Button
aprè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
Button
pour qu'il se trouve sous le bord inférieur de l'élémentSwitch
Round 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
TextView
avec un ID de ressource nommétip_result
et le texteTip Amount
. - Appliquez une contrainte au bord de fin de
TextView
par 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_service
etok_service
pour 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
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 champEditText
. - Vous pouvez créer une liste d'options exclusives avec des éléments
RadioButtons
, regroupés dans un élémentRadioGroup
. - Un élément
RadioGroup
peut être vertical ou horizontal, et vous pouvez spécifier quel élémentRadioButton
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émentTextView
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 composantConstraintLayout
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 ?