1. Avant de commencer
Cet atelier de programmation présente une nouvelle application appelée Lemonade, que vous créerez par vous-même. Il vous explique les différentes étapes à suivre pour mener à bien le projet, y compris la configuration et les tests dans Android Studio.
Cet atelier de programmation est différent des autres ateliers de ce cours. Contrairement aux précédents ateliers de programmation, celui-ci n'a pas pour objectif de vous fournir un tutoriel détaillé sur la création d'une application. Au lieu de cela, il vous aide à configurer un projet que vous devrez réaliser de manière indépendante, avec les instructions nécessaires pour finaliser une application et vérifier vous-même votre travail.
Au lieu du code de solution, nous proposons une suite de tests intégrés à l'application que vous téléchargerez. Vous exécuterez ces tests dans Android Studio (nous vous montrerons comment procéder plus tard dans cet atelier) et vérifierez si votre code passe ces tests avec succès. Plusieurs tentatives seront peut-être nécessaires. Même les développeurs professionnels ne réussissent pas tous les tests dès le premier essai. Une fois que votre code aura réussi tous les tests, vous pourrez considérer ce projet comme terminé.
Nous sommes conscients que vous pourriez préférer avoir directement accès à la solution. Toutefois, nous ne vous fournissons pas le code de la solution, car nous souhaitons que vous vous mettiez à la place d'un développeur professionnel. Peut-être devrez-vous renforcer des compétences différentes que vous ne maîtrisez pas encore, par exemple :
- Apprendre des termes, messages d'erreur et extraits de code dans l'application que vous ne reconnaissez pas.
- Tester le code, lire les erreurs, puis modifier le code et le tester à nouveau.
- Réviser le contenu précédent du module 1 sur les bases d'Android afin de rafraîchir vos connaissances.
- Comparer le code dont vous savez qu'il fonctionne (code fourni dans le projet ou code de solution d'autres applications du module 1) avec le code que vous écrivez.
Cette nouvelle tâche peut sembler intimidante au premier abord, mais nous avons la certitude que si vous avez mené à bien le module 1, vous êtes fin prêt pour ce projet. Prenez votre temps et n'abandonnez pas. Faites-vous confiance !
Conditions préalables
- Ce projet est destiné aux utilisateurs qui ont terminé le module 1 du cours sur les principes de base d'Android en Kotlin.
Objectifs de l'atelier
- Vous créerez une application Lemonade simple sur la base des compétences acquises lors du module 1.
Ce dont vous avez besoin
- Un ordinateur sur lequel est installé Android Studio
2. Présentation de l'application
Bienvenue dans le projet : application Lemonade.
Nous vous avons recruté dans notre équipe pour que vous nous aidiez à concrétiser notre projet de préparation de citronnade en ligne. L'objectif est de concevoir une application mobile simple et interactive qui vous permettra de presser des citrons jusqu'à ce que vous remplissiez un verre de citronnade. Considérez cela comme une métaphore ou simplement comme un moyen amusant de passer le temps.
La version finale de l'application Lemonade ne doit comprendre qu'un seul écran. Lorsque les utilisateurs lanceront l'application pour la première fois, ils devront choisir un citron en appuyant sur la photo d'un citronnier.
Lorsque l'utilisateur appuiera sur le citronnier, un citron lui sera présenté. Il devra appuyer sur l'écran autant de fois que nécessaire (le nombre exact de pressions requises est généré de manière aléatoire) pour presser le citron avant de passer à l'écran suivant.
Lorsque l'utilisateur aura appuyé sur le citron le nombre de fois nécessaires pour le presser, une image représentant un verre de citronnade qu'il pourra "boire" apparaîtra.
Une fois que l'utilisateur aura cliqué pour boire la citronnade, le verre se videra. Il pourra alors appuyer à nouveau sur l'image pour revenir au premier écran, puis choisir un autre citron dans l'arbre.
Cette application vise la simplicité et est organisée en une seule activité. Les différents états de l'application (par exemple si l'utilisateur sélectionne un citron, presse le citron, boit la citronnade et, enfin, vide le verre) seront représentés par une machine à état. Ce terme théorique peut sembler sophistiqué, mais signifie simplement que l'état de l'application (c'est-à-dire le texte et l'image présentés à l'utilisateur) sera déterminé par une variable qui contient l'état de l'application (select
, squeeze
, etc.). Cet état sera mis à jour avec toutes les autres variables requises, puis l'interface utilisateur sera configurée séparément (pour définir l'image et le texte) une fois toutes les mises à jour effectuées.
Toutes les variables correspondant à l'état de l'application ont été définies pour vous. Votre tâche consiste à créer la mise en page de l'application et à implémenter la logique qui permettra à l'interface utilisateur de passer d'un état à l'autre comme prévu.
Tester votre code
Pour l'application Lemonade (et les futurs projets), des tests automatisés seront mis à votre disposition pour vous permettre de vérifier que le code fonctionne comme prévu.
En quoi consistent les tests automatisés ? En développement logiciel, vous pouvez considérer le terme "test" comme du code qui permet de vérifier qu'un autre code fonctionne. Il examine les sorties (comme le contenu des éléments d'interface utilisateur qui apparaissent à l'écran) pour vérifier qu'elles correspondent aux entrées, ce qui est aussi appelé "scénario de test". Le projet initial de l'application Lemonade inclut quelques tests que vous pourrez exécuter pour vous assurer que vous avez correctement implémenté la logique. Nous aborderons ces tests plus en détail ultérieurement. Pour le moment, téléchargez le code de démarrage et commencez à créer l'application Lemonade.
3. Premiers pas
Télécharger le code du projet
Notez que le nom du dossier est android-basics-kotlin-lemonade-app
. Sélectionnez ce dossier lorsque vous ouvrez le projet dans Android Studio.
Pour obtenir le code de cet atelier de programmation et l'ouvrir dans Android Studio, procédez comme suit :
Obtenir le code
- Cliquez sur l'URL indiquée. La page GitHub du projet s'ouvre dans un navigateur.
- Vérifiez que le nom de la branche correspond au nom spécifié dans l'atelier de programmation. Par exemple, dans la capture d'écran suivante, le nom de la branche est main.
- Sur la page GitHub du projet, cliquez sur le bouton Code pour afficher une fenêtre pop-up.
- Dans la fenêtre pop-up, cliquez sur le bouton Download ZIP (Télécharger le fichier ZIP) pour enregistrer le projet sur votre ordinateur. Attendez la fin du téléchargement.
- Recherchez le fichier sur votre ordinateur (il se trouve probablement dans le dossier Téléchargements).
- Double-cliquez sur le fichier ZIP pour le décompresser. Un dossier contenant les fichiers du projet est alors créé.
Ouvrir le projet dans Android Studio
- Lancez Android Studio.
- Dans la fenêtre Welcome to Android Studio (Bienvenue dans Android Studio), cliquez sur Open (Ouvrir).
Remarque : Si Android Studio est déjà ouvert, sélectionnez l'option de menu File > Open (Fichier > Ouvrir).
- Dans l'explorateur de fichiers, accédez à l'emplacement du dossier du projet décompressé (il se trouve probablement dans le dossier Téléchargements).
- Double-cliquez sur le dossier de ce projet.
- Attendez qu'Android Studio ouvre le projet.
- Cliquez sur le bouton Run (Exécuter) pour créer et exécuter l'application. Assurez-vous qu'elle fonctionne correctement.
Prenez le temps de vous familiariser avec le projet initial. Portez une attention particulière au fichier MainActivity.kt
.
Dans MainActivity.kt
, vous trouverez plusieurs variables permettant de représenter l'état actuel de l'application. Vous en aurez besoin lors d'une étape ultérieure pour rendre l'application interactive. Même si la quantité de code indiquée ici peut être impressionnante, vous n'avez pas besoin de modifier les éléments non identifiés par la mention TODO. Vous trouverez des instructions spécifiques dans les pages suivantes.
Vous remarquerez également que le projet comprend un autre package, com.example.lemonade (androidTest).
Il inclut les tests automatisés que vous utiliserez pour vérifier que la fonctionnalité que vous implémentez dans MainActivity.kt
est correcte. Nous y reviendrons plus tard. Pour le moment, l'heure est venue de créer l'application, en commençant par l'interface utilisateur.
4. Créer votre interface utilisateur
L'application Lemonade ne nécessite qu'une mise en page de base. Deux vues suffisent pour implémenter toutes ses fonctionnalités.
- La vue
TextView
fournira des instructions à l'utilisateur. - La vue
ImageView
affichera un graphique basé sur l'état actuel de l'application (par exemple, un citron à presser).
Vous créerez cette mise en page dans activity_main.xml
.
Utilisez votre connaissance de l'éditeur de mise en page pour créer une mise en page qui ressemble à l'exemple ci-dessous, avec à la fois un affichage centré à l'écran et la vue TextView
au-dessus de la vue ImageView
.
5. Rendre votre application interactive
Une fois la mise en page terminée, ouvrez MainActivity.kt
. C'est là que vous implémenterez toute la logique de l'application. Vous remarquerez qu'il y a déjà beaucoup de code. De nombreux commentaires sont également signalés par la mention // TODO:
(voir l'exemple ci-dessous). Il s'agit des tâches que vous devrez effectuer.
Voici les trois étapes de base à suivre pour que l'application Lemonade fonctionne.
- Configurez la vue
ImageView
lemonImage
pour qu'elle réponde aux entrées utilisateur. - Implémentez
clickLemonImage()
pour mettre à jour l'état de l'application. - Implémentez
setViewElements()
pour mettre à jour l'interface utilisateur en fonction de l'état actuel de l'application.
Examinons chaque tâche une par une.
Étape 1 : Configurer la vue ImageView
En appuyant sur la vue de l'image, l'application devrait passer d'un état à un autre. À la fin de onCreate()
, notez que vous avez deux écouteurs à configurer.
setOnClickListener()
doit mettre à jour l'état de l'application. Pour ce faire, utilisezclickLemonImage()
.setOnLongClickListener()
répond aux événements où l'utilisateur appuie de manière prolongée sur une image (lorsqu'il appuie sur l'image et qu'il n'enlève pas immédiatement son doigt). Pour les événements impliquant une pression prolongée du doigt, un widget, appelé snackbar, s'affichera au bas de l'écran afin d'indiquer à l'utilisateur le nombre de fois où il a pressé le citron. Pour ce faire, exécutez la méthodeshowSnackbar()
.
À l'étape suivante, vous implémenterez la logique permettant de modifier l'état de l'application.
Étape 2 : Implémenter clickLemonImage()
Une fois l'étape précédente terminée, la méthode clickLemonImage()
est désormais appelée chaque fois que l'utilisateur appuie sur l'image. Cette méthode permet de faire passer l'application de l'état actuel vers le suivant et de mettre à jour les variables, si nécessaire. Il existe quatre états possibles : SELECT
, SQUEEZE
, DRINK
et RESTART
. L'état actuel est représenté par la variable lemonadeState
. Cette méthode doit exécuter une action différente pour chaque état.
SELECT
: passez à l'étatSQUEEZE
, définissezlemonSize
(nombre de pressions requises) en appelant la méthodepick()
et spécifiez 0 poursqueezeCount
(nombre de fois où l'utilisateur a pressé le citron).SQUEEZE
: incrémentezsqueezeCount
de 1 et diminuezlemonSize
de 1. N'oubliez pas qu'un citron nécessite un nombre variable de pressions pour que l'application passe d'un état à l'autre. Ne passez à l'étatDRINK
que si la nouvelle valeur delemonSize
est égale à 0. Sinon, l'application doit rester à l'étatSQUEEZE
.DRINK
: passez à l'étatRESTART
et définissezlemonSize
sur -1.RESTART
: revenez à l'étatSELECT
.
Une fois que vous avez géré toutes les mises à jour et les transitions entre les états, veillez à appeler setViewElements()
pour mettre à jour l'interface utilisateur en fonction du nouvel état.
Étape 3 : Implémenter setViewElements()
La méthode setViewElements()
permet de mettre à jour l'interface utilisateur en fonction de l'état de l'application. Le texte et l'image doivent être mis à jour avec les valeurs ci-dessous pour correspondre à l'état (lemonadeState
).
SELECT
:
- Texte : Cliquez pour sélectionner un citron !
- Image :
R.drawable.lemon_tree
SQUEEZE
:
- Texte : Cliquez pour presser le citron !
- Image :
R.drawable.lemon_squeeze
DRINK
:
- Texte : Cliquez pour boire votre citronnade !
- Image :
R.drawable.lemon_drink
RESTART
:
- Texte : Cliquez pour recommencer.
- Image :
R.drawable.lemon_restart
Utiliser des ressources de chaîne
Sur Android, presque tout est une ressource. La définition de ressources auxquelles vous pourrez ensuite accéder dans votre application est au centre du développement sur Android.
Les ressources permettent de définir des couleurs, des images, des mises en page, des menus et des valeurs de chaîne. Leur avantage est que rien n'est codé en dur. Tout est défini dans ces fichiers de ressources, puis peut être référencé dans le code de l'application. La plus simple de ces ressources (et la plus courante) est une ressource de chaîne, qui permet l'utilisation de texte localisé et flexible.
Les chaînes ou le texte statique peuvent être stockés dans un fichier distinct appelé string.xml, dans le sous-dossier "values" du dossier "res".
Pour chaque extrait de texte à afficher dans l'application (libellé d'un bouton ou texte d'une vue TextView
, par exemple), vous devez d'abord définir le texte dans le fichier res/values/strings.xml
. Chaque entrée correspond à une clé (représentant l'ID du texte) et à une valeur (le texte lui-même). Par exemple, si vous souhaitez qu'un bouton affiche Submit (Envoyer), ajoutez la ressource de chaîne suivante à res/values/strings.xml
:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello!</string>
<string name="submit_label">Submit</string>
</resources>
Pour accéder à la ressource directement dans le code, utilisez simplement les méthodes getResources.getString()
ou getString()
afin de parvenir à la valeur correspondant à l'ID de ressource, R.string.submit_label
.
val submitText = getResources().getString(R.string.submit_label)
Pour définir directement le texte de la ressource de chaîne sur la vue TextView, vous pouvez appeler setText()
au niveau de l'objet TextView et transmettre l'ID de ressource.
val infoTextView: TextView = findViewById(R.id.info_textview)
infoTextView.setText(R.string.info_text)
Les ressources de chaîne peuvent également contenir des caractères spéciaux pour mettre en forme le texte. Par exemple, vous pouvez avoir une ressource de chaîne qui vous permet d'insérer un autre extrait texte dans la chaîne.
<string name="ingredient_tablespoon">%1$d tbsp of %2$s</string>
Dans le code, vous devez accéder à la ressource de chaîne et la mettre en forme en transmettant des arguments.
getResources().getString(R.string.ingredient_tablespoon, 2, "cocoa powder")
Lors de la déclaration de la ressource de chaîne, chaque argument est numéroté dans l'ordre dans lequel il apparaît (1
, 2
, etc.) et comporte une lettre permettant d'identifier le type (d
pour le nombre décimal, s
pour la chaîne, etc.). Les arguments dont le type est approprié peuvent être transmis dans l'appel de getString()
.
2 tbsp of cocoa powder
Pour en savoir plus, consultez la documentation sur les ressources de chaîne.
6. Exécuter votre application
Une fois que vous avez créé l'interface utilisateur de l'application et que vous avez implémenté l'activité principale, il est temps de voir le fruit de vos efforts. Exécutez l'application via le menu Exécuter > Exécuter l'application pour lancer l'émulateur.
L'application devrait maintenant être entièrement interactive. Vous devriez pouvoir appuyer sur l'image pour passer d'un état à un autre.
Lorsque le citron s'affiche à l'écran, vous pouvez également appuyer de manière prolongée sur la vue ImageView
pour que le snackbar situé en bas affiche le nombre total de fois où le citron a été pressé. Prenez le temps de faire passer l'application d'un état à l'autre plusieurs fois. Vous pouvez être fier de vous !
7. Instructions de test
Tester votre application
Vous avez terminé de mettre en œuvre l'application Lemonade, mais dans le domaine du développement de logiciels professionnels, l'écriture du code est rarement la dernière étape. Outre le code d'application, les applications de qualité professionnelle incluent également un code de test qui s'exécute pour vérifier que le code fonctionne comme prévu et que les modifications qui lui sont apportées n'introduisent pas de nouveau bug. Ce processus est appelé "test automatisé". Ce projet n'a pas pour objectif de vous apprendre à créer des tests automatisés. Toutefois, l'application Lemonade est fournie avec des tests vous permettant de vérifier que vous avez correctement implémenté le projet. Mettez-les à profit pour vous autoévaluer et pour déterminer si toutes les exigences du projet ont été respectées et si des modifications doivent être apportées à l'application.
Qu'est-ce qu'un "test" ? Les tests sont simplement des extraits de code inclus dans votre projet Android Studio. Ils exécutent une partie du code de votre application et peuvent "aboutir" ou "échouer", selon que le code de l'application fonctionne comme prévu ou non.
Où trouver et exécuter les tests de votre application ? Les tests de l'application Lemonade se trouvent dans la cible de test. Une cible est un terme de développement logiciel qui désigne un ensemble de classes qui ont été regroupées. Par exemple, l'application Lemonade existe dans une cible appelée "app", tandis que les tests existent dans une cible appelée "LemonadeTests". Bien que la cible LemonadeTests puisse accéder au code de la cible de l'application, elle est complètement distincte. Le code de l'application ne contient aucun code de test.
Dans la vue "Android", les cibles de test portent le même nom de package que l'application, mais contiennent en plus la mention (androidTest) entre parenthèses.
Il est également important de connaître quelques termes clés concernant le code de test.
- Suite de tests : cible qui inclut tous les scénarios de test.
- Scénario de test : classe composée de tests individuels pour les fonctionnalités associées (l'application Lemonade ne comprend qu'un seul scénario de test, mais les applications plus volumineuses en ont souvent beaucoup plus).
- Test : fonction qui teste un élément spécifique.
Un scénario de test peut contenir plusieurs tests, et la suite de tests d'un projet peut comporter plusieurs scénarios de test.
Exécuter vos tests
Pour exécuter les tests, vous pouvez effectuer l'une des opérations suivantes.
Pour un scénario de test unique, ouvrez une classe de scénario de test et cliquez sur la flèche verte à gauche de la déclaration de classe. Vous pouvez ensuite sélectionner l'option "Run" (Exécuter) dans le menu. Tous les tests seront exécutés dans le scénario de test.
Souvent, il suffit d'exécuter un seul test, notamment lorsqu'un test a échoué et que tous les autres ont réussi. Il est possible d'exécuter un seul test de la même manière que vous le feriez pour un scénario de test complet. Utilisez la flèche verte et sélectionnez l'option Exécuter.
Si vous avez plusieurs scénarios de test, vous pouvez également exécuter l'ensemble de la suite de tests. Comme pour l'exécution de l'application, cette option se trouve dans le menu Exécuter.
Notez qu'Android Studio utilise par défaut la dernière cible que vous avez exécutée (applications, cibles de test, etc.). Par conséquent, si le menu indique toujours Run > Run ‘app' (Exécuter > Exécuter l'application), vous pouvez exécuter la cible de test en sélectionnant Run > Run (Exécuter > Exécuter).
Sélectionnez ensuite la cible de test dans le menu pop-up.
Les résultats des tests sont affichés dans l'onglet Exécuter. Dans le volet de gauche, la liste des tests ayant échoué s'affiche, le cas échéant. Les échecs sont signalés par un point d'exclamation rouge à côté du nom de la fonction. Les tests réussis sont marqués d'une coche verte.
Si un test échoue, la sortie textuelle vous fournit des informations pour vous aider à résoudre le problème sous-jacent.
Par exemple, dans le message d'erreur ci-dessus, le test vérifie si une vue TextView
utilise une ressource de chaîne spécifique. Cependant, le test échoue. Le texte situé après "Expected" (Attendu) et "Got" (Reçu) ne correspond pas à la valeur attendue par le test. Dans cet exemple, la chaîne utilisée dans TextView
n'est pas squeeze_count
dans la réalité, comme ce que le test s'attend à voir.
8. Partager votre application (facultatif)
Lorsque vous aurez bu tous les verres de citronnade que vous voulez, créez une capture de votre écran préféré et partagez-la sur Twitter pour partager ce que vous avez appris. Taguez @AndroidDev et ajoutez le hashtag #AndroidBasics.