• 20 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

Ce cours existe en livre papier.

Vous pouvez être accompagné et mentoré par un professeur particulier par visioconférence sur ce cours.

J'ai tout compris !

Mis à jour le 26/02/2019

Les autres ressources

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Maintenant que vous avez parfaitement compris ce qu'étaient les ressources, pourquoi et comment les utiliser, je vous propose de voir… comment les créer. :D Il existe une grande variété ressources différences, c'est pourquoi on ne les verra pas toutes. Je vous présenterai ici uniquement les plus utiles et plus compliquées à utiliser.

Un dernier conseil avant d'entrer dans le vif du sujet : créez le plus de ressources possible, dès que vous le pouvez. Ainsi, vos applications seront plus flexibles, et le développement sera plus évident.

Aspect général des fichiers de ressources

Nous allons voir comment sont constitués les fichiers de ressources qui contiennent des values (je les appellerai « données » désormais). C'est encore une fois un fichier XML, mais qui revêt cette forme-ci :

<?xml version="1.0" encoding="utf-8"?>
<resources>
  …
</resources>

Afin d'avoir un petit aperçu de ce à quoi elles peuvent ressembler, on va d'abord observer les fichiers que crée Android à la création d'un nouveau projet. Double-cliquez sur le fichier res/values/strings.xml pour ouvrir une nouvelle fenêtre (voir figure suivante).

Fenêtre d'édition des données
Fenêtre d'édition des données

On retrouve à gauche toutes les ressources qui sont contenues dans ce fichier. Là il y en a deux, c'est plutôt facile de s'y retrouver, mais imaginez un gros projet avec une cinquantaine voire une centaine de données, vous risquez de vite vous y perdre. Si vous voulez éviter ce type de désagréments, vous pouvez envisager deux manières de vous organiser :

  • Réunir les données d'un même type pour une activité dans un seul fichier. Par exemple strings.xml pour toutes les chaines de caractères. Le problème est qu'il vous faudra créer beaucoup de fichiers, ce qui peut être long.

  • Ou alors mettre toutes les données d'une activité dans un fichier, ce qui demande moins de travail, mais nécessite une meilleure organisation afin de pouvoir s'y retrouver.

Si vous souhaitez opter pour la seconde organisation, alors le meilleur moyen de s'y retrouver est de savoir trier les différentes ressources à l'aide du menu qui se trouve en haut de la fenêtre. Il vous permet de filtrer la liste des données en fonction de leur type. Voici la signification de tous les boutons :

  • Bouton 1Bouton 1

    : Afficher uniquement les chaînes de caractères (String)

  • Bouton 2Bouton 2

    : Afficher uniquement les couleurs (Color)

  • Bouton 3Bouton 3

    : Afficher uniquement les dimensions (Dimension)

  • Bouton 4Bouton 4

    : Afficher uniquement les drawables (Drawable)

  • Bouton 5Bouton 5

    : Afficher uniquement les styles et thèmes (Style)

  • Bouton 6Bouton 6

    : Afficher uniquement les éléments qui appartiennent à un ensemble (à un tableau par exemple) (Item)

  • Bouton 7Bouton 7

    : Afficher uniquement les tableaux de chaînes de caractères (String Array)

  • Bouton 8Bouton 8

    : Afficher uniquement les tableaux d'entiers (Int Array)

  • Bouton 9Bouton 9

    : Ranger la liste dans l'ordre alphabétique du nom de la donnée. Un second clic range dans l'ordre alphabétique inverse

De plus, le menu du milieu (voir figure suivante) vous permet de créer ou supprimer des données.

Menu du milieu
  • Le bouton Add… permet d'ajouter une nouvelle donnée.

  • Le bouton Remove… permet de supprimer une donnée.

  • Le bouton Up permet d'augmenter d'un cran la position de la donnée dans le tableau central.

  • Le bouton Down permet de diminuer d'un cran la position de la donnée dans le tableau central.

Personnellement, je n'utilise cette fenêtre que pour avoir un aperçu rapide de mes données. Cependant, dès qu'il me faut effectuer des manipulations, je préfère utiliser l'éditeur XML. D'ailleurs je ne vous apprendrai ici qu'à travailler avec un fichier XML, de manière à ce que vous ne soyez pas totalement déboussolés si vous souhaitiez utiliser une autre extension que l'ADT. Vous pouvez naviguer entre les deux interfaces à l'aide des deux boutons en bas de la fenêtre, visibles à la figure suivante.

Vous pouvez naviguer entre les deux interfaces

Référence à une ressource

Nous avons déjà vu que quand une ressource avait un identifiant, Android s'occupait d'ajouter au fichier R.java une référence à l'identifiant de cette ressource, de façon à ce que nous puissions la récupérer en l'inflatant. La syntaxe de la référence était :

R.type_de_ressource.nom_de_la_ressource

Ce que je ne vous ai pas dit, c'est qu'il était aussi possible d'y accéder en XML. Ce n'est pas tellement plus compliqué qu'en Java puisqu'il suffit de respecter la syntaxe suivante :

@type_de_ressource/nom_de_la_ressource

Par exemple pour une chaîne de caractères qui s'appellerait salut, on y ferait référence en Java à l'aide de R.strings.salut et en XML avec @string/salut.

Enfin, si la ressource à laquelle on essaie d'accéder est une ressource fournie par Android dans son SDK, il suffit de respecter la syntaxe Android.R.type_de_ressource.nom_de_la_ressource en Java et @android:type_de_ressource/nom_de_la_ressource en XML.

Les chaînes de caractères

Vous connaissez les chaînes de caractères, c'est le mot compliqué pour désigner un texte. La syntaxe est évidente à maîtriser, par exemple si nous voulions créer une chaîne de caractères de nom « nomDeLExemple » et de valeur Texte de la chaîne qui s'appelle "nomDeLExemple" :

<string name="nomDeLExemple">Texte de la chaîne qui s appelle nomDeLExemple</string>

Et ils ont disparu où, les guillemets et l'apostrophe ?

Commençons par l'évidence, s'il n'y a ni espace, ni apostrophe dans le nom, c'est parce qu'il s'agit du nom d'une variable comme nous l'avons vu précédemment, par conséquent il faut respecter les règles de nommage d'une variable standard.

Pour ce qui est du texte, il est interdit d'insérer des apostrophes ou des guillemets. Sinon, comment Android peut-il détecter que vous avez fini d'écrire une phrase ? Afin de contourner cette limitation, vous pouvez très bien échapper les caractères gênants, c'est-à-dire les faire précéder d'un antislash (\).

<string name="nomDeLExemple">Texte de la chaîne qui s\'appelle \"nomDeLExemple\"</string>

Vous pouvez aussi encadrer votre chaîne de guillemets afin de ne pas avoir à échapper les apostrophes ; en revanche vous aurez toujours à échapper les guillemets.

<string name="nomDeLExemple">"Texte de la chaîne qui s'appelle \"nomDeLExemple\""</string>

Application

Je vous propose de créer un bouton et de lui associer une chaîne de caractères qui contient des balises HTML (<b>, <u> et <i>) ainsi que des guillemets et des apostrophes. Si vous ne connaissez pas de balises HTML, vous allez créer la chaîne suivante : « Vous connaissez l'histoire de <b>"Tom Sawyer"</b> ? ». Les balises <b></b> vous permettent de mettre du texte en gras.

Instructions
  • On peut convertir notre String en Spanned. Spanned est une classe particulière qui représente les chaînes de caractères qui contiennent des balises HTML et qui peut les interpréter pour les afficher comme le ferait un navigateur internet. Cette transformation se fait à l'aide de la méthode statique Spanned Html.fromHtml (String source).

  • On mettra ce Spanned comme texte sur le bouton avec la méthode void setText (CharSequence text).

Ma correction

Le fichier strings.xml :

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <string name="hello">Hello World, TroimsActivity!</string>
  <string name="histoire">Vous connaissez l\'histoire de <b>\"Tom Sawyer\"</b> ?</string>
  <string name="app_name">Troims</string>
</resources>

Et le code Java associé :

import android.app.Activity;
import android.os.Bundle;
import android.text.Html;
import android.text.Spanned;
import android.widget.Button;

public class StringExampleActivity extends Activity {
  Button button = null;
  String hist = null;
    
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
        
    // On récupère notre ressource au format String
    hist = getResources().getString(R.string.histoire);
    // On le convertit en Spanned
    Spanned marked_up = Html.fromHtml(hist);

    button = new Button(this);
    // Et on attribue le Spanned au bouton
    button.setText(marked_up);

    setContentView(button);
  }
}

Formater des chaînes de caractères

Le problème avec nos chaînes de caractères en tant que ressources, c'est qu'elles sont statiques. Elles ne sont pas destinées à être modifiées et par conséquent elles ne peuvent pas s'adapter.

Imaginons une application qui salue quelqu'un, qui lui donne son âge, et qui s'adapte à la langue de l'utilisateur. Il faudrait qu'elle dise : « Bonjour Anaïs, vous avez 22 ans » en français et « Hello Anaïs, you are 22 » en anglais. Cette technique est par exemple utilisée dans le jeu Civilization IV pour traduire le texte en plusieurs langues. Pour indiquer dans une chaîne de caractères à quel endroit se situe la partie dynamique, on va utiliser un code. Dans l'exemple précédent, on pourrait avoir Bonjour %1$s, vous avez %2$d ans en français et Hello %1$s, you are %2$d en anglais. L'astuce est que la première partie du code correspond à une position dans une liste d'arguments (qu'il faudra fournir) et la seconde partie à un type de texte (int, float, string, bool, …). En d'autres termes, un code se décompose en deux parties :

  • %n avec « n » étant un entier naturel (nombre sans virgule et supérieur à 0) qui sert à indiquer le rang de l'argument à insérer (%1 correspond au premier argument, %2 au deuxième argument, etc.) ;

  • $x, qui indique quel type d'information on veut ajouter ($s pour une chaîne de caractères et $d pour un entier — vous pourrez trouver la liste complète des possibilités sur cette page).

On va maintenant voir comment insérer les arguments. Il existe au moins deux manières de faire.

On peut le faire en récupérant la ressource :

Resources res = getResources();
// Anaïs ira en %1 et 22 ira en %2
String chaine = res.getString(R.string.hello, "Anaïs", 22);

Ou alors sur n'importe quelle chaîne avec une fonction statique de String :

// On n'est pas obligé de préciser la position puisqu'on n'a qu'un argument !
String iLike = String.format("J'aime les $s", "pâtes");
Application

C'est simple, je vais vous demander d'arriver au résultat visible à la figure suivante.

L'exemple à reproduire
Ma solution

On aura besoin de deux fichiers strings.xml : un dans le répertoire values et un dans le répertoire values-en qui contiendra le texte en anglais :

values/strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <string name="hello">Bonjour %1$s, vous avez %2$d ans.</string>
  <string name="app_name">Deums</string>
</resources>

values-en/strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <string name="hello">Hello %1$s, you are %2$d.</string>
  <string name="app_name">Deums</string>
</resources>

De plus on va donner un identifiant à notre TextView pour récupérer la chaîne :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:orientation="vertical" >

  <TextView
    android:id="@+id/vue"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content" />

</LinearLayout>

Et enfin, on va récupérer notre TextView et afficher le texte correct pour une femme s’appelant Anaïs et qui aurait 22 ans :

import android.app.Activity;
import android.content.res.Resources;
import android.os.Bundle;
import android.widget.TextView;

public class DeumsActivity extends Activity {
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
        
    setContentView(R.layout.main);
        
    Resources res = getResources();
    // Anaïs se mettra dans %1 et 22 ira dans %2, mais le reste changera en fonction de la langue du terminal !
    String chaine = res.getString(R.string.hello, "Anaïs", 22);
    TextView vue = (TextView)findViewById(R.id.vue);
    vue.setText(chaine);
  }
}

Et voilà, en fonction de la langue de l'émulateur, le texte sera différent !

Les drawables

La dénomination « drawable » rassemble tous les fichiers « dessinables » (oui, ce mot n'existe pas en français, mais « drawable » n'existe pas non plus en anglais après tout :p ), c'est-à-dire les dessins ou les images. Je ne parlerai que des images puisque ce sont les drawables les plus utilisés et les plus indispensables.

Les images matricielles

Android supporte trois types d'images : les PNG, les GIF et les JPEG. Sachez que ces trois formats n'ont pas les mêmes usages :

  • Les GIF sont peu recommandés. On les utilise sur internet pour les images de moindre qualité ou les petites animations. On va donc les éviter le plus souvent.

  • Les JPEG sont surtout utilisés en photographie ou pour les images dont on veut conserver la haute qualité. Ce format ne gère pas la transparence, donc toutes vos images seront rectangulaires.

  • Les PNG sont un bon compromis entre compression et qualité d'image. De plus, ils gèrent la transparence. Si le choix se présente, optez pour ce format-là.

Il n'y a rien de plus simple que d'ajouter une image dans les ressources, puisqu'il suffit de faire glisser le fichier à l'emplacement voulu dans Eclipse (ou mettre le fichier dans le répertoire voulu dans les sources de votre projet), comme à la figure suivante, et le drawable sera créé automatiquement.

On se contente de glisser-déposer l'image dans le répertoire voulu et Android fera le reste
On se contente de glisser-déposer l'image dans le répertoire voulu et Android fera le reste

Les images extensibles

Utiliser une image permet d'agrémenter son application, mais, si on veut qu'elle soit de qualité pour tous les écrans, il faudrait une image pour chaque résolution, ce qui est long. La solution la plus pratique serait une image qui s'étire sans jamais perdre en qualité ! Dans les faits, c'est difficile à obtenir, mais certaines images sont assez simples pour qu'Android puisse déterminer comment étirer l'image en perdant le moins de qualité possible. Je fais ici référence à la technique 9-Patch. Un exemple sera plus parlant qu'un long discours : on va utiliser l'image visible à la figure suivante, qui est aimablement prêtée par ce grand monsieur, qui nous autorise à utiliser ses images, même pour des projets professionnels, un grand merci à lui.

Nous allons utiliser cette image pour l'exemple
Nous allons utiliser cette image pour l'exemple

Cette image ne paye pas de mine, mais elle pourra être étendue jusqu'à former une image immense sans pour autant être toute pixellisée. L'astuce consiste à indiquer quelles parties de l'image peuvent être étendues, et le SDK d'Android contient un outil pour vous aider dans votre démarche. Par rapport à l'endroit où vous avez installé le SDK, il se trouve dans \Android\tools\draw9patch.bat. Vous pouvez directement glisser l'image dans l'application pour l'ouvrir ou bien aller dans File > Open 9-patch… (voir figure suivante).

Le logiciel Draw 9-patch

Ce logiciel contient trois zones différentes :

  • La zone de gauche représente l'image et c'est dans cette zone que vous pouvez dessiner. Si, si, essayez de dessiner un gros cœur au milieu de l'image. Je vous ai eus ! Vous ne pouvez en fait dessiner que sur la partie la plus extérieure de l'image, la bordure qui fait un pixel de largeur et qui entoure l'image.

  • Celle de droite est un aperçu de l'image élargie de plusieurs façons. Vous pouvez voir qu'actuellement les images agrandies sont grossières, les coins déformés et de gros pixels sont visibles.

  • Et en bas on trouve plusieurs outils pour vous aider dans votre tâche.

Si vous passez votre curseur à l'intérieur de l'image, un filtre rouge s'interposera de façon à vous indiquer que vous ne devez pas dessiner à cet endroit (mais vous pouvez désactiver ce filtre avec l'option Show lock). En effet, l'espèce de quadrillage à côté de votre image indique les zones de transparence, celles qui ne contiennent pas de dessin. Votre rôle sera d'indiquer quels bords de l'image sont extensibles et dans quelle zone de l'objet on pourra insérer du contenu. Pour indiquer les bords extensibles on va tracer un trait d'une largeur d'un pixel sur les bords haut et gauche de l'image, alors que des traits sur les bords bas et droite déterminent où peut se placer le contenu. Par exemple pour cette image, on pourrait avoir (il n'y a pas qu'une façon de faire, faites en fonction de ce que vous souhaitez obtenir) le résultat visible à la figure suivante.

Indiquez les zones extensibles ainsi que l'emplacement du contenu
Indiquez les zones extensibles ainsi que l'emplacement du contenu

Vous voyez la différence ? Les images étirées montrent beaucoup moins de pixels et les transitions entre les couleurs sont bien plus esthétiques ! Enfin pour ajouter cette image à votre projet, il vous suffit de l'enregistrer au format .9.png, puis de l'ajouter à votre projet comme un drawable standard.

L'image suivante vous montre plus clairement à quoi correspondent les bords :

À gauche, la zone qui peut être agrandie, à droite la zone dans laquelle on peut écrire
À gauche, la zone qui peut être agrandie, à droite la zone dans laquelle on peut écrire
Les commandes
  • Le slider Zoom vous permet de vous rapprocher ou vous éloigner de l'image originale.

  • Le slider Patch scale vous permet de vous rapprocher ou vous éloigner des agrandissements.

  • Show patches montre les zones qui peuvent être étendue dans la zone de dessin.

  • Show content vous montre la zone où vous pourrez insérer du contenu (image ou texte) dans Android.

  • Enfin, vous voyez un bouton en haut de la zone de dessin, Show bad patches, qui une fois coché vous montre les zones qui pourraient provoquer des désagréments une fois l'image agrandie ; l'objectif sera donc d'en avoir le moins possible (voire aucune).

Les styles

Souvent quand on fait une application, on adopte un certain parti pris en ce qui concerne la charte graphique. Par exemple, des tons plutôt clairs avec des boutons blancs qui font une taille de 20 pixels et dont la police du texte serait en cyan. Et pour dire qu'on veut que tous les boutons soient blancs, avec une taille de 20 pixels et le texte en cyan, il va falloir indiquer pour chaque bouton qu'on veut qu'il soit blanc, avec une taille de 20 pixels et le texte en cyan, ce qui est très vite un problème si on a beaucoup de boutons !

Afin d'éviter d'avoir à se répéter autant, il est possible de définir ce qu'on appelle un style. Un style est un ensemble de critères esthétiques dont l'objectif est de pouvoir définir plusieurs règles à différents éléments graphiques distincts. Ainsi, il est plus évident de créer un style « Boutons persos », qui précise que la cible est « blanche, avec une taille de 20 pixels et le texte en cyan » et d'indiquer à tous les boutons qu'on veut qu'ils soient des « Boutons persos ». Et si vous voulez mettre tous vos boutons en jaune, il suffit simplement de changer l'attribut blanc du style « Bouton persos » en jaune .

Voici la forme standard d'un style :

<resources>
  <style name="nom_du_style" parent="nom_du_parent">
    <item name="propriete_1">valeur_de_la_propriete_1</item>
    <item name="propriete_2">valeur_de_la_propriete_2</item>
    <item name="propriete_3">valeur_de_la_propriete_3</item>
    …
    <item name="propriete_n">valeur_de_la_propriete_n</item>
  </style>
</resources>

Voici les règles à respecter :

  • Comme d'habitude, on va définir un nom unique pour le style, puisqu'il y aura une variable pour y accéder.

  • Il est possible d'ajouter des propriétés physiques à l'aide d'<item>. Le nom de l'<item> correspond à un des attributs destinés aux Vues, qu'on a déjà étudiés. Par exemple pour changer la couleur d'un texte, on va utiliser l'attribut android:textColor.

  • Enfin, on peut faire hériter notre style d'un autre style — qu'il ait été défini par Android ou par vous-mêmes — et ainsi récupérer ou écraser les attributs d'un parent.

Le style suivant permet de mettre du texte en cyan :

<style name="texte_cyan">
  <item name="android:textColor">#00FFFF</item>
</style>

Les deux styles suivants héritent du style précédent en rajoutant d'autres attributs :

<style name="texte_cyan_grand" parent="texte_cyan">
  <!-- On récupère la couleur du texte définie par le parent -->
  <item name="android:textSize">20sp</item>
</style>
<style name="texte_rouge_grand" parent="texte_cyan_grand">
  <!-- On écrase la couleur du texte définie par le parent, mais on garde la taille -->
  <item name="android:textColor">#FF0000</item>
</style>

Il est ensuite possible d'attribuer un style à une vue en XML avec l'attribut style="identifiant_du_style". Cependant, un style ne s'applique pas de manière dynamique en Java, il faut alors préciser le style à utiliser dans le constructeur. Regardez le constructeur d'une vue : public View (Context contexte, AttributeSet attrs). Le paramètre attrs est facultatif, et c'est lui qui permet d'attribuer un style à une vue. Par exemple :

Button bouton = new Button (this, R.style.texte_rouge_grand);

Les animations

Pour donner un peu de dynamisme à notre interface graphique, on peut faire en sorte de bouger, faire tourner, agrandir ou faire disparaître une vue ou un ensemble de vues. Mais au préalable sachez qu'il est possible de placer un système de coordonnées sur notre écran de manière à pouvoir y situer les éléments. Comme à la figure suivante, l'axe qui va de gauche à droite s'appelle l'axe X et l'axe qui va de haut en bas s'appelle l'axe Y.

L'axe horizontal est X, l'axe vertical est Y

Voici quelques informations utiles :

  • Sur l'axe X, plus on se déplace vers la droite, plus on s'éloigne de 0.

  • Sur l'axe Y, plus on se déplace vers le bas, plus on s'éloigne de 0.

  • Pour exprimer une coordonnée, on utilise la notation (X, Y).

  • L'unité est le pixel.

  • Le point en haut à gauche a pour coordonnées (0, 0).

  • Le point en bas à droite a pour coordonnées (largeur de l'écran, hauteur de l'écran).

Définition en XML

Contrairement aux chaînes de caractères et aux styles, les animations ne sont pas des données mais des ressources indépendantes, comme l'étaient les drawables. Elles doivent être définies dans le répertoire res/anim/.

Pour un widget

Il existe quatre animations de base qu'il est possible d'effectuer sur une vue (que ce soit un widget ou un layout !). Une animation est décrite par un état de départ pour une vue et un état d'arrivée : par exemple on part d'une vue visible pour qu'elle devienne invisible.

Transparence

<alpha> permet de faire apparaître ou disparaître une vue.

  • android:fromAlpha est la transparence de départ avec 0.0 pour une vue totalement transparente et 1.0 pour une vue totalement visible.

  • android:toAlpha est la transparence finale voulue avec 0.0 pour une vue totalement transparente et 1.0 pour une vue totalement visible.

Rotation

<rotate> permet de faire tourner une vue autour d'un axe.

  • android:fromDegrees est l'angle de départ.

  • android:pivotX est la coordonnée du centre de rotation sur l'axe X (en pourcentages par rapport à la gauche de la vue, par exemple 50% correspond au milieu de la vue et 100% au bord droit).

  • android:pivotY est la coordonnée du centre de rotation sur l'axe Y (en pourcentages par rapport au plafond de la vue).

  • android:toDegrees est l'angle voulu à la fin.

Taille

<scale> permet d'agrandir ou de réduire une vue.

  • android:fromXScale est la taille de départ sur l'axe X (1.0 pour la valeur actuelle).

  • android:fromYScale est la taille de départ sur l'axe Y (1.0 pour la valeur actuelle).

  • android:pivotX (identique à <rotate>).

  • android:pivotY (identique à <rotate>).

  • android:toXScale est la taille voulue sur l'axe X (1.0 pour la valeur de départ).

  • android:toYScale est la taille voulue sur l'axe Y (1.0 pour la valeur de départ).

Mouvement

<translate> permet de faire subir une translation à une vue (mouvement rectiligne).

  • android:fromXDelta est le point de départ sur l'axe X (en pourcentages).

  • android:fromYDelta est le point de départ sur l'axe Y (en pourcentages).

  • android:toXDelta est le point d'arrivée sur l'axe X (en pourcentages).

  • android:toYDelta est le point d'arrivée sur l'axe Y (en pourcentages).

Sachez qu'il est en plus possible de regrouper les animations en un ensemble et de définir un horaire de début et un horaire de fin. Le nœud qui représente cet ensemble est de type <set>. Tous les attributs qui sont passés à ce nœud se répercuteront sur les animations qu'il contient. Par exemple :

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
  <scale
    android:fromXScale="1.0"
    android:fromYScale="1.0"
    android:toXScale="2.0"
    android:toYScale="0.5"
    android:pivotX="50%"
    android:pivotY="50%" />
  <alpha
    android:fromAlpha="1.0"
    android:toAlpha="0.0" />
</set>

Dans ce code, le scale et l'alpha se feront en même temps ; cependant notre objectif va être d'effectuer d'abord le scale, et seulement après l'alpha. Pour cela, on va dire au scale qu'il démarrera exactement au lancement de l'animation, qu'il durera 0,3 seconde et on dira à l'alpha de démarrer à partir de 0,3 seconde, juste après le scale. Pour qu'une animation débute immédiatement, il ne faut rien faire, c'est la propriété par défaut. En revanche pour qu'elle dure 0,3 seconde, il faut utiliser l'attribut android:duration qui prend comme valeur la durée en millisecondes (ça veut dire qu'il vous faut multiplier le temps en secondes par 1000). Enfin, pour définir à quel moment l'alpha débute, c'est-à-dire avec quel retard, on utilise l'attribut android:startOffset (toujours en millisecondes). Par exemple, pour que le scale démarre immédiatement, dure 0,3 seconde et soit suivi par un alpha qui dure 2 secondes, voici ce qu'on écrira :

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
  <scale
    android:fromXScale="1.0"
    android:fromYScale="1.0"
    android:toXScale="2.0"
    android:toYScale="0.5"
    android:pivotX="50%"
    android:pivotY="50%"
    android:duration="300"/>
  <alpha
    android:fromAlpha="1.0"
    android:toAlpha="0.0"
    android:startOffset="300"
    android:duration="2000"/>
</set>

Un dernier détail. Une animation permet de donner du dynamisme à une vue, mais elle n'effectuera pas de changements réels sur l'animation : l'animation effectuera l'action, mais uniquement sur le plan visuel. Ainsi, si vous essayez ce code, Android affichera un mouvement, mais une fois l'animation finie, les vues redeviendront exactement comme elles étaient avant le début de l'animation. Heureusement, il est possible de demander à votre animation de changer les vues pour qu'elles correspondent à leur état final à la fin de l'animation. Il suffit de rajouter les deux attributs android:fillAfter="true" et android:fillEnabled="true".

Enfin je ne vais pas abuser de votre patience, je comprendrais que vous ayez envie d'essayer votre nouveau joujou. Pour ce faire, c'est très simple, utilisez la classe AnimationUtils.

// On crée un utilitaire de configuration pour cette animation
Animation animation = AnimationUtils.loadAnimation(contexte_dans_lequel_se_situe_la_vue, identifiant_de_l_animation);
// On l'affecte au widget désiré, et on démarre l'animation
le_widget.startAnimation(animation);
Pour un layout

Si vous effectuez l'animation sur un layout, alors vous aurez une petite manipulation à faire. En fait, on peut très bien appliquer une animation normale à un layout avec la méthode que nous venons de voir, mais il se trouve qu'on voudra parfois faire en sorte que l'animation se propage parmi les enfants du layout pour donner un joli effet.

Tout d'abord, il vous faut créer un nouveau fichier XML, toujours dans le répertoire res/anim, mais la racine de celui-ci sera un nœud de type <layoutAnimation> (attention au « l » minuscule !). Ce nœud peut prendre trois attributs. Le plus important est android:animation puisqu'il faut y mettre l'identifiant de l'animation qu'on veut passer au layout. On peut ensuite définir le délai de propagation de l'animation entre les enfants à l'aide de l'attribut android:delay. Le mieux est d'utiliser un pourcentage, par exemple 100% pour attendre que l'animation soit finie ou 0% pour ne pas attendre. Enfin, on peut définir l'ordre dans lequel l'animation s'effectuera parmi les enfants avec android:animationOrder, qui peut prendre les valeurs : normal pour l'ordre dans lequel les vues ont été ajoutées au layout, reverse pour l'ordre inverse et random pour une distribution aléatoire entre les enfants.

On obtient alors :

<?xml version="1.0" encoding="utf-8"?>
<layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android" 
  android:delay="10%"
  android:animationOrder="random"
  android:animation="@anim/animation_standard"
/>

Puis on peut l'utiliser dans le code Java avec :

LayoutAnimationController animation = AnimationUtils.loadLayoutAnimation(contexte_dans_lequel_se_situe_la_vue, identifiant_de_l_animation);
layout.setLayoutAnimation(animation);

Un dernier raffinement : l'interpolation

Nos animations sont super, mais il manque un petit quelque chose qui pourrait les rendre encore plus impressionnantes. Si vous testez les animations, vous verrez qu'elles sont constantes, elles ne montrent pas d'effets d'accélération ou de décélération par exemple. On va utiliser ce qu'on appelle un agent d'interpolation, c'est-à-dire une fonction mathématique qui va calculer dans quel état doit se trouver notre animation à un moment donné pour simuler un effet particulier.

Regardez la figure suivante : en rouge, sans interpolation, la vitesse de votre animation reste identique pendant toute la durée de l'animation. En bleu, avec interpolation, votre animation démarrera très lentement et accélérera avec le temps. Heureusement, vous n'avez pas besoin d'être bons en maths pour utiliser les interpolateurs. :D

La vitesse de l'animation s'accélère avec le temps

Vous pouvez rajouter un interpolateur à l'aide de l'attribut android:interpolator, puis vous pouvez préciser quel type d'effet vous souhaitez obtenir à l'aide d'une des valeurs suivantes :

  • @android:anim/accelerate_decelerate_interpolator : la vitesse est identique au début et à la fin de l'animation, mais accélère au milieu.

  • @android:anim/accelerate_interpolator : pour une animation lente au début et plus rapide par la suite.

  • @android:anim/anticipate_interpolator : pour que l'animation commence à l'envers, puis revienne dans le bon sens.

  • @android:anim/anticipate_overshoot_interpolator : pour que l'animation commence à l'envers, puis revienne dans le bon sens, dépasse la valeur finale puis fasse marche arrière pour l'atteindre.

  • @android:anim/bounce_interpolator : pour un effet de rebond très sympathique.

  • @android:anim/decelerate_interpolator : pour que l'animation démarre brutalement et se termine lentement.

  • @android:anim/overshoot_interpolator : pour une animation qui démarre normalement, dépasse la valeur finale, puis fasse marche arrière pour l'atteindre.

Enfin, si on place un interpolateur dans un <set>, il est probable qu'on veuille le partager à tous les enfants de ce <set>. Pour propager une interpolation à tous les enfants d'un ensemble, il faut utiliser l'attribut android:shareInterpolator="true".

En ce qui concerne les répétitions, il existe aussi un interpolateur, mais il y a plus pratique. Préférez plutôt la combinaison des attributs android:repeatCount et android:repeatMode. Le premier définit le nombre de répétitions de l'animation qu'on veut effectuer (-1 pour un nombre infini, 0 pour aucune répétition, et n'importe quel autre nombre entier positif pour fixer un nombre précis de répétitions), tandis que le second s'occupe de la façon dont les répétitions s'effectuent. On peut lui affecter la valeur restart (répétition normale) ou alors reverse (à la fin de l'animation, on effectue la même animation mais à l'envers).

L'évènementiel dans les animations

Il y a trois évènements qui peuvent être gérés dans le code : le lancement de l'animation, la fin de l'animation, et chaque début d'une répétition. C'est aussi simple que :

animation.setAnimationListener(new AnimationListener() {
  public void onAnimationEnd(Animation _animation) {
    // Que faire quand l'animation se termine ? (n'est pas lancé à la fin d'une répétition)
  }

  public void onAnimationRepeat(Animation _animation) {
    // Que faire quand l'animation se répète ?
  }

  public void onAnimationStart(Animation _animation) {
    // Que faire au premier lancement de l'animation ?
  }
});
  • Chaque type de ressources aura comme racine un élement resources qui contiendra d'autres éléments hiérarchisant les ressources. Elles peuvent être accessibles soit par la partie Java R.type_de_ressource.nom_de_la_ressource soit par d'autres fichiers XML @type_de_ressource/nom_de_la_ressource.

  • Les chaînes de caractères sont déclarées par des éléments string.

  • Android supporte 3 types d'images : PNG, JPEG et GIF, dans l'ordre du plus conseillé au moins conseillé.

  • 9-Patch est une technologie permettant de rendre des images extensibles en gardant un rendu net.

  • Les styles permettent de définir ou redéfinir des propriétés visuelles existantes pour les utiliser sur plusieurs vues différentes. Ils se déclarent par un élément style et contiennent une liste d'item.

  • Les animations se définissent par un ensemble d'éléments :

    • <alpha> pour la transparence d'une vue.

    • <rotate> pour la rotation d'une vue autour d'un axe.

    • <scale> pour la modification de l'échelle d'une vue.

    • <translate> pour le déplacement d'une vue.

  • L'animation sur un layout se fait grâce à la déclaration d'un élément LayoutAnimation.

  • Une interpolation peut être appliquée à une animation pour modifier les variations de vitesse de l'animation.

Exemple de certificat de réussite
Exemple de certificat de réussite