Malt Freelance — Flutter Clone App

Aimen SIJOUMI
9 min readApr 19, 2020

--

Cet article est une version presque “copier-coller” de l’article rédigé sur mon blog que vous pouvez trouver à l’adresse suivante : Malt Freelance — Flutter Clone App

Depuis quelques mois désormais, je me suis relancé dans le développement des applications mobiles. J’avais commencé 5 années en arrière où je ne faisais exclusivement des applications sur iOS. Cependant, produire des applications natives reste chronophage : on écrit 2 fois le même code même s’il y a des différences sur les plateformes (Android et iOS).

En conséquence, les applications hybrides peuvent être une bonne alternative au natives (si nous utilisons des fonctionnalités communes sur ces plateformes). Il existe plusieurs framework pour écrire des applications en hybride, il y a :

  • React-Native, l’un des plus populaire
  • Ionic
  • NativeScript
  • Flutter

Flutter : j’ai découvert ce Framework il y a environ 6 mois, et franchement, c’est de la bombe 💣. Sa structure arborescente est super intuitive, un langage de programmation (Dart) très simple. Mais là où Google a fait fort, c’est sur la documentation de flutter (tout comme les autres documentations de Google). J’ai pu facilement prendre la main sur ce Framework et compris les fondamentaux (tout le monde y arriverait en un rien de temps).

Pourquoi “Malt Freelance” ?

Fallait bien s’occuper pendant le confinement non (tout en restant à la maison) 😅 ? Plus sérieusement, je cherchais des inspirations de design pour un de mes projets personnels et je suis tombé sur l’application de Malt.

Pour résumer simplement, Malt est une plateforme qui met en relation des freelances et des clients afin de réaliser différents projets (un concept que je trouve génial !).

Mais là où l’équipe de Malt a tout déchiré 💣 (selon moi), c’est leur application. Voici quelques captures d’écran :

Visuellement, je la trouve vraiment top, les couleurs et la typographie sont super bien choisis.

Elle a certains effets que j’ai trouvé tellement naturel et intuitifs :

  • Lorsqu’on essayer de scroller la page vers le haut (tandis qu’on se trouve en haut de celle-ci), la ligne où se trouve « Activité » et l’avatar « AS » restent à leur place.
  • Lorsqu’on clique sur l’avatar « AS », un modal apparaît, ce qui évite de « changer de page » avec une navigation. Cela rend, à mon sens, l’utilisation très naturelle.

J’ai également testé l’application sur Android, l’effet est également similaire. Je voulais donc savoir comment ont-ils fait ce rendu si naturel (si natif).

Alors je les ai contacté, et la réponse était qu’ils avaient développé l’application iOS avec Swift et celle d’Android avec Kotlin. Après cette réponse, j’étais agréablement surpris, les 2 applications se ressemblaient tellement. J’ai donc creusé le sujet 🧐, j’ai bien analysé celles-ci et j’ai trouvé quelques légères différences 🤭.

A ce moment, j’ai eu un moment d’euphorie face à ce rendu magnifique 😱😨, à la fois excitant mais frustrant : est-ce possible d’avoir le même rendu en flutter ? J’ai donc envoyé un message à un très bon ami, Tyron, qui fait aussi du flutter :

Alors GO !! L’objectif : avoir un rendu similaire à l’application initiale, avoir cet effet de scroll et avoir un modal qui s’affiche en venant du bas de l’application.

Le design

Avant de se lancer dans le code, il faut toujours se poser, réfléchir, se documenter et modéliser. Afin que tout le monde partage ma vision, j’ai réalisé le wireframe associé à la première page. Pour réaliser ce wireframe, j’ai utilisé Figma, une plateforme qui permet de créer des maquettes simplement et gratuitement (il y a bien plus de fonctionnalités). Voici les wireframes :

On a 2 pages, l’une qu’on nommera « Activité » et l’autre qu’on nommera « Modal ».

Dans la page « Activité », on peut voir plusieurs éléments principaux, il y en a 5 :

  1. Cela sera notre application bar, on le verra dans le chapitre suivant
  2. Cette partie représente une bloc contenant 2 lignes : un titre et un sous-titre. J’ai volontairement mis une couleur de fond afin qu’on s’en rend compte
  3. Un bloque de contenu avec du blanc comme couleur de fond
  4. Similaire au point 2
  5. Un autre bloque de contenu sans couleur de fond

On a l’impression que l’ensemble de ces bloques flottent, car il y a un dégradé bleu en arrière-plan, on verra comment reproduire cet effet dans l’implémentation.

Dans la page « Modal » nous avons :

  1. Un tiret permettant, de visuellement, montrer qu’on peut descendre cet élément vers le bas
  2. Une bordure qui est arrondi
  3. Une liste de champs

L’implémentation du design

Pour commencer

Pour commencer, on créer un projet flutter. On peut tout supprimer dans le fichier main.dart et faire comme suit. On créera un dossier screens et un fichier activity_screen.dart.

A partir de là, notre application plantera car notre build de ActivityScreen ne retourne rien. On va donc devoir alimenter cette classe.

Le dégradé de couleur

Pour avoir notre fameux dégradé de couleur, on va ajouter dans notre classe ActivityScreen un Container dans un Scaffold. Par la suite, on ajoute une décoration qui sera un gradient linéaire :

Ici, on force la couleur de fond du Scaffold à transparent pour que ce soit le gradient de couleur qui prend place.

Pour le dégradé, on le commence en haut à gauche de l’écran et on le termine en bas à droite. Évidemment, pour un dégradé de couleur, il est préférable d’en avoir plusieurs, c’est pour cela qu’on fourni une liste de couleur.

Voici donc le résultat :

Les titres et bloques de contenu

On remarque que les titres et les bloques sont formatés de la même manière. On va donc s’occuper de la partie 2 et 3 de la page « Activité ».

Premièrement, dans l’application d’origine, on a un ScrollView qui permet de se déplacer de haut en bas au sein de la page, c’est donc ce que nous allons ajouter :

On a désormais une vue qui est « scrollable », donc s’il y avait plus de contenu, on aurait la possibilité de descendre et remonter au sein la page.

L’ « App bar »

C’est la partie qui a mis le plus de temps à être réalisée. Quand j’ai recherché des pistes pour implémenter cette partie, je suis tombé la plupart du temps sur une SilverAppBar, ce qui donne le rendu suivant :

Mais ce n’est pas ce que je recherchais, je ne voulais pas de couleur de fond, je ne voulais pas que le texte se déplace en haut à gauche. Alors j’ai regardé l’implémentation de la SilverAppBar :

J’ai regardé ce commentaire pendant 5 minutes, je me disais « mince, alors on ne peut fournir qu’un Widget de type Text … ». Puis après cette réflexion, je me suis rappelé d’une phrase des Widget Of The Week : « In flutter, all is Widget ». Eureka 🤓🧐 ! Pourquoi insérer forcément un Widget Text ? On peut très bien insérer une Row et ajouter la personnalisation que l’on souhaite (là se trouve la force de flutter avec ses Widgets 💪🏻).

Le résultat est très impressionnant, même si j’ai mis plusieurs heures à essayer de comprendre comment gérer le SilverAppBar avec le reste, le rendu est significatif : peu de code, même pas un ScrollController à gérer !

Par contre, la critique que j’ai est la suivante : le paramètre se nomme title, on pense qu’il n’y a que du texte qui peut s’y insérer … Je me demande donc si ce n’est pas une mauvaise pratique de ma part d’y avoir inséré autre chose que du texte ? L’essentiel c’est que ça réponde à mon besoin !

Ça commence vraiment à ressembler à l’application d’origine 🤩 :

L’apparition du modal

Pour le modal, l’équipe de flutter nous a fourni une fonction permettant d’afficher un modal avec la fonction showModalBottomSheet. Cette fonction prend en paramètre un builder qui permet de personnaliser le rendu du modal. Lorsque l’utilisateur clique sur son avatar, on affichera le modal, afin d’avoir cet effet « cliquable », on entoure le CircleAvartar par un InkWell (vous pourrez voir le détail dans les sources).

Bim bam boum !

On veut désormais ajouter le « tiret » se trouvant au-dessus. Pour ça, on va ajouter cette partie de code juste au-dessus du Widget Expanded :

L’astuce pour avoir ce « tiret » qui flotte au dessus du modal réside dans le fait d’avoir une colonne. L’entièreté de notre modal est transparent, et dans ce modal on a une colonne. Une colonne correspond à une succession d’éléments disposé verticalement.

Alors on ajoute juste un Container avec une certaine hauteur, largeur et des bordures arrondies (comme le modal est transparent, on croit que le tiret flotte).

Et voilà 🙄 :

Désormais, il ne reste plus qu’à ajouter le contenu pour la page d’Activité et pour le Modal.

Le résultat final

Voici les captures d’écran du résultat de ce « clonage » d’application. Il y a quelques différences entre l’application originale (Malt Freelance) et celle-ci.

Je vais terminer par commenter l’ « expérience utilisateur » de l’application en flutter. Pour une application hybride, je trouve ça vraiment réactif et fluide, ce point m’a particulièrement surpris. Je reste tout de même soucieux du détail, et j’ai remarqué une légère différence entre l’application native et celle en flutter concernant le scroll, il doit y avoir 1 ms de latence. Mais cette différence ne se sent que si vraiment on essaye de la trouver 🤔.

Le second point est le suivant : je n’ai utilisé aucun package ou plugin supplémentaire. Tout a été réalisé avec l’ensemble des composants de base de flutter, ce qui en dit beaucoup sur sa richesse d’API.

Les sources de cette application se trouvent sur mon Github.

Ce qu’il manque

Il manque certains éléments pour que ce soit vraiment un clone (du point de vu des fonctionnalités). Ces éléments sont listés dans le README du projet :

  • La view qui vient englober la status bar quand on commence à scroller. J’avais implémenté juste le changement de couleur de texte, mais je n’ai pas creusé sur le fait d’afficher une petite vue avec son animation.
  • Pour le modal, les éléments sont dans une ListView, lorsqu’on scroll tout en faut, cela s’arrête. Ce qu’il manquerait, c’est lorsqu’on scroll tout en faut, le modal commence à se réduire. En recherchant, j’ai vu que c’était réalisable avec un DraggableScrollableSheet.

--

--

Aimen SIJOUMI

Un Data Engineer passionné par la Data et le développement mobile.