Créer sa propre animation sur Android à l’aide des Path et des Drawables

le 13/02/2019 par Rémi Dormoy
Tags: Software Engineering

Depuis que j’ai commencé le développement Android il y a deux ans, j’ai toujours été attiré par la partie UI et notamment sur comment challenger les maquettes pour les rendre plus dynamiques. J’ai souvent vu dans cette pratique un moyen rapide d'apporter de la valeur ajoutée dans mon travail.

Il y a quelques temps, une bonne amie designeuse m’a montré le compte instagram de cuberto design sur lequel on peut trouver de nombreux concepts sympa et innovants. Sur nombre d’entre eux, je me suis retrouvé sans idées pour les implémenter. Et sur l’une d’entre elles, le commentaire était assez explicite : _“_We often receive comments for our designs like "is it possible to code it?". If you hire Cuberto for both design and development, there won't be such questions at all!”

Et sur le moment, je me suis dit que si j’avais la chance de travailler avec un designer qui ose de tels écrans, ce serait un crève-coeur de lui dire non parce que je n’ai pas les compétences de matérialiser ses projets.

Notre premier dessin

J’ai donc commencé à écumer internet pour trouver une solution et je suis tombé sur un premier article expliquant comment manipuler les Path pour pouvoir dessiner à la main le Drawable que l’on veut.

Le principe, très simple, est de “dessiner” un nuage de points puis de le remplir avec la couleur de notre choix. Plus précisément, de créer une sous-classe de la classe Drawable, puis dans sa méthode draw de créer un Path (le nuage de points) puis de le remplir avec un Paint (notre couleur). Ensuite, il suffit de donner notre Drawable comme background à n’importe quelle View et on peut dessiner ce que l’on veut. Essayons avec un simple carré :

Voir le lien github

Pour ce carré, on commence par se rendre au point en haut à gauche (en Android, l’axe y va du haut vers le bas), puis dans chacun des trois autres coins et enfin on ferme le Path. Hop!, on se retrouve avec un carré de la couleur de notre Paint.

Un peu de math dans tout ça

Nous allons maintenant essayer de tracer un background qui suit l’arrondi d’un floating button comme celui du site de material.io.

Pour atteindre ce résultat, plongeons dans les souvenirs de nos cours de maths. Les points d’un cercle sont pour un angle a et un rayon r : x=cos(a) * r et y=sin(a)*r. Il ne nous reste plus qu’à tracer tous les points des angles allant de ???? à 2????. Avec ceci, nous pouvons nous préparer à implémenter la méthode draw de notre nouveau Drawable :

Voir le lien github

Ce qui nous donne, une fois lancé sur téléphone :

Le tracé n’est pas parfait, il manque les arrondis au niveau des coins, mais pour cet article, on va se satisfaire de ce résultat et essayer de travailler avec.

Et si on l’animait ?

Si vous avez cliqué sur le lien de material.io, vous avez pu voir que le bouton ne se contente pas de rester sagement en place mais qu’il se compresse puis saute et que la ligne se déforme en suivant son mouvement. Après avoir réussi à dessiner notre background, il va donc falloir lui faire suivre les changements de taille et de hauteur de notre floating button. Pour cela, on va simplement, à chaque “instant” de notre animation, updater la taille, largeur et translation de notre bouton dans le calcul de notre Path, puis invalider le drawable :

Voir le lien github

Revenons à la première animation

Maintenant que l’on s’est fait la main avec les Path, revenons à la première animation de Cuberto design. Pour commencer, avant de passer à l’implémentation, il faut trouver la courbe d’une fonction qui collerait avec l’image que l’on a envie de dessiner. Une nouvelle fois, armé des souvenirs des mathématiques qu’il nous reste de nos études, on peut ouvrir n’importe quel calculateur que l’on trouve en ligne et essayer des formules jusqu’à trouver celle qui nous convient. Pour ma part, j’ai choisi celle-ci :

Une fois la fonction sélectionnée, nous allons l’adapter à un drawable, en prenant le soin de la tourner de 90°. Puis avec quelques facteurs en plus, on ajuste la largeur, la hauteur et la position de la bosse :

Voir le lien github

On obtient un premier jet pas tout à fait satisfaisant à première vue mais qui va nous servir de base pour la suite, et qui peut valider ou non le choix de notre fonction :

Maintenant que l’on a cette base, nous pouvons commencer à l’animer, que ce soit sur l’axe X ou Y suivant le déplacement de notre doigt, en gardant le même principe que pour le bouton de la première animation.

Voir le lien github

             

En faisant varier notre yPeak (hauteur de la bosse) et notre progress (abscisse de la bosse) on obtient l’image de gauche. Puis avec un peu de contenu, l’image de droite.

Jouons un peu

Bien que le résultat ne soit pas totalement similaire à la maquette de départ, nous allons nous arrêter ici pour cette animation. Si vous retournez sur Dribble ou n'importe quel blog de design, vous trouverez très facilement de quoi vous inspirer, et vous lancer dans la création de votre propre animation. Personnellement, j'ai continué avec les trois suivantes   :

Une SeekBar

Un pull to refresh

Un bouton d'ajout à tirer

À chaque fois, on applique la même mécanique. D’abord on trouve la bonne fonction à appliquer. Puis on trace notre nuage de point une première fois pour le valider. Et enfin on l’anime en faisant changer certains paramètres clefs.

Conclusion

Au fur et à mesure que j’avançais sur les différentes animations, la première chose qui m’a sauté aux yeux fut la rapidité avec laquelle j’avançais maintenant que je maîtrisais la technique. Je suis passé de deux jours de travail pour la première à quelques dizaines de minutes pour la dernière, sur des difficultés relativement similaires. Si le coût d’apprentissage est certain, je ne pense plus que le temps d’intégration de ce type d’animation soit rédhibitoire pour les intégrer à un “vrai” projet. Enfin, après avoir essayé de créer une animation venant de mon esprit plutôt que d’une maquette et avoir abouti sur quelque chose de vraiment peu élégant, je me suis dit que savoir implémenter une animation ne fait pas de nous un designer.

Le code est disponible ici