Environnement de développement Androïd

Objectifs

L’objectif principal de ce travail pratique et de se familiariser avec l’environnement de développement Androïd, notamment :

  • créer un nouveau projet Androïd,
  • créer une machine virtuelle pour tester le projet,
  • comprendre l’organisation des composants d’une application Androïd,
  • composer une interface graphique basique, et
  • y associer des fonctionnalités.

On verra dans la suite comment faire des interfaces plus complexes.

Démarrer l’environnement de développement Androïd

Dans ce travail pratique, nous utilisons l’environnement de développement Androïd créé par Google. Cet environnement de développement intégré (EDI) est une version modifiée de notre cher ami, Eclipse. Pour le lancer dans les salles de TP, lancer Android Dev Tools dans la section Developpement du lanceur d’applications. Vous pouvez également le lancer en ligne de commande en tapant :

:::bash
/cal/softs/adt-bundle-linux/eclipse/eclipse &

Créer une machine virtuelle

Dans un premier temps, il faut créer une machine virtuelle qui va simuler un dispositif Androïd.

  • Cliquer l’icône d’un robot dans un smartphone (Android Virtual Device Manager) pour lancer le configurateur de machines virtuelles.
  • Cliquer le bouton « New »
  • Configurer un Nexus One, avec le plus grand « API Level » disponible choisi comme « Target ». NB : Le simulateur est très lent. Sauf si vous auriez vraiment besoin de simuler un dispositif plus puissant, avec plus de mémoire et un écran plus large, il vaut mieux faire une configuration moins lourd.
  • Ne pas lancer le dispositif. Eclipse le fera automatiquement lors qu’on lance notre application.

La configuration devrait ressembler à celle là :

Nouvelle Machine Virtuelle

Créer un premier projet

Nous allons maintenant créer un premier projet Androïd. Notre application sera un convertisseur de monnaies. Dans sa première version, il y aura trois étiquettes, trois champs de texte, et deux boutons : convertir et RÀZ (remet à zéro). Commençons.

  • Créer un « New Android Application Project » en faisant File -> New...
  • Pour le nom de l’application, saisir quelque chose comme « Sous ».
  • Pour le nom du projet, laisser « Sous ».
  • Pour le nom du paquetage, mettre « fr.enst.infsi351.votre_nom.sous ».
  • Vérifier que la configuration ressemble à celle dessous, puis faire « Next ».
  • Laisser les options par défaut, puis faire « Next ».
  • Idem.
  • Choisir BlankActivity, puis faire « Next ».
  • Laisser les options par défaut, puis faire « Finish ».
Nouveau projet

Si tout s’est bien déroulé, vous auriez un joli projet Androïd. Testons-le en ouvrant notre MainActivity.java dans le dossier src, puis en cliquant le bouton « Run » pour le compiler et lancer. Si tout va bien, Eclipse lancera notre nouvelle machine virtuelle. Au bout de quelques minutes, une fois la machine bien démarrée (et vous bien marré), vous devrez voir un joli robot qui dit « Hello World ».

Organisation d’un projet Androïd

Regardons un peu plus proche le projet qu’Eclipse nous a créé. Vous avez peut-être remarqué qu’il y a un ou deux million de dossiers dans notre projet, dont quelques uns qui nous concerne aujourd’hui :

  • src — ce dossier contient le code source pour notre application, dont
    • MainActivity.java qui est notre écran principal. Rappelons qu’une activité correspond à peu près à un écran en Androïd.
  • res — contient les ressources non-code de l’application
    • drawable-* — les images brutes à composer dans l’interface. Les versions différentes correspondent à la résolution du dispositif.
    • layout — les descriptions de l’interface sous format XML, dont notre
      • activity_main.xml qui décrit l’interface pour MainActivity.java.
    • values — nous ignorons ces fichiers sauf :
      • strings.xml qui contient des définitions des chaines de caractères qu’on utilise dans l’interface

La première chose qui est un peu bizarre est cette notion de séparation des chaines de caractères dans leur propre fichier. Cet approche nous permet de facilement créer des localisations et traductions du texte dans le projet.

Les fichiers layout/*.xml sont un peu comme les designs qu’on fait dans Qt Designer. C’est un fichier XML qui décrit l’interface qui sera affichée sur l’écran. Commençons là.

Composer une interface

Ouvrir layout/activity_main.xml. Initialement, Eclipse nous propose un éditeur graphique pour composer l’interface. C’est un très bon outil, mais pour mieux apprendre ce qui se passe réellement, nous allons dans un premier temps utiliser l’interface XML. Cliquer l’onglet en bas de l’éditeur avec le nom activity_main.xml pour passer à la vue XML.

L’interface qu’on voit corresponde à notre « Hello World », créé automatiquement par Eclipse lorsque l’on crée un nouveau projet. Dans un premier temps, changer le RelativeLayout en LinearLayout et modifier les attributs pour que ça ressemble à :

:::xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity" >

Notre première version de l’interface contiendra quatre rangs : un pour une étiquette et champs de texte pour saisir le montant en euros, un pour saisir le taux d’échange, un pour indiquer la valeur équivalente en dollars, et un pour les deux boutons.

Pour créer ces rangs, il suffit de mettre un layout à l’intérieur du LinearLayout, créant une hiérarchie de widgets. Le LinearLayout que nous avons déjà créé aura une orientation verticale. Pour créer les rangs, ça suffit donc de mettre d’autres LinearLayouts dedans, mais avec un orientation horizontale. (Bien entendu, il y a d’autres layouts possibles.)

Testons la nouvelle version pour assurez que nous n’avons pas cassé l’interface. Si vous ne voyez pas « Hello World », déboguer le layout jusqu’à ce que ça marche.

Ensuite, rajouter un autre LinearLayout dans le premier. Il n’y aura plus besoin des attributs xmlns:* et tools:context. Virer-les, et changer l’orientation en horizontal. De plus, on ne veut plus que la hauteur soit celle du parent. Changer-la donc en wrap_content, nous laissant avec :

:::xml
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal">

Déplacer le TextView dans ce rang et changer son texte en @string/euros_label. Si vous essayez de lancer l’application, Eclipse se plaindra que cette valeur n’est pas encore définie. Le compilateur est vigilant, mais nous ne sommes pas esclave à la machine ! On la définira tout à l’heure, quand on le veut. Ensuite, rajouter un champs de texte :

:::xml
<EditText android:id="@+id/edit_euros"
        android:inputType="numberDecimal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:hint="@string/euros_label" />

Noter que nous avons donné un android:id attribut à cet item. Cet attribut permettra d’accéder à ce widget dans notre code java. Le + avant id indique que l’on définie un nouvel objet avec cet identifiant.

Tester encore l’interface pour vérifier que ça marche. Normalement, on verra que ça ne compile pas, parce que nous n’avons pas encore définie la @string/euros_label.

Ouvrir le fichier strings.xml dans res/values et y rajouter une entrée pour euros_label avec la valeur « Euros » en suivant le modèle des autres strings définies dans le fichier.

Tester encore et déboguer si nécessaire.

Une fois content que ça marche, rajouter un autre rang pour la taux d’échange. Re-compiler et lancer pour tester. Puis rajouter un rang pour le résultat. Indice : pour créer un champ de texte non-modifiable, utiliser les attributs android:enabled="false" et android:focusable="false".

Tester l’application encore une fois.

Remarquer que la mise-en-place de l’interface n’est pas terrible. Les widgets sont dimensionnés par la taille de leur contenu et non par la place disponible. Il existe une autre option, android:layout_weight qui donne un poids relatif au widget dans le layout. C’est comme faire un cocktail : le poids et relatif aux autres composants (e.g. pour faire une interface délicieuse, faire une part TextView pour deux parts EditText. Miam !). Par défaut, un widget à un poids 0. Quand on utilise un android:layout_weight pour une dimension, on ne veut plus calculer la taille en fonction des contenus, donc on met aussi android:layout_width (ou height, le cas échéant) à 0dp :

:::xml
<EditText android:id="@+id/edit_euros"
    android:inputType="numberDecimal"
    android:layout_weight="1"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:hint="@string/euros_label" />

Dans un nouveau rang, rajouter les boutons. Un bouton s’écrit comme ça :

:::xml
<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="@string/button_convert"
    android:onClick="convert" />

L’attribut android:onClick relie le bouton à une méthode de l’activité associée tout à l’heure avec le tools:context attribut. Nous allons définir cette méthode prochainement. Mais d’abord, ne pas oublier de définir les strings dans strings.xml.

Implementer la fonctionnalité

La méthode de rappel (« callback ») associé à un widget via android:onClick devrait être void et devrait accepter un seule paramètre, la View qui à déclenché l’action :

:::java
public void maMethode(View sender) { ... }

Implementer les méthodes de rappel référencée dans le layout. Pour retrouver un widget défini dans le layout par son identifiant, utiliser :

:::java
EditText editText = (EditText) findViewById(R.id.identifiant_du_widget);

Pour retrouver et modifier la valeur d’un champ de texte, les méthodes editText.getText().toString() et editText.setText(blaBlaString) pourraient être utiles.

Améliorer l’interface

Félicitations, votre application Androïd marche. S’il vous reste du temps, penser à améliorer l’interface. Google propose des bons guides sur le site web Androïd :

(Je n’ai pas trouvé de bonnes traductions en français, mais ça n’empêche pas qu’elles existent !)

Quelles modifications feriez-vous ? (Astuce : vous avez vu plusieurs techniques pour concevoir des interfaces avant de les implementer.)

La semaine prochaine, nous verrons comment afficher plusieurs écrans avec plusieurs activités.