h30x

2021-06-01

Développement mobile avec Flutter

En ce moment, tout le monde parle de Flutter. C'est un framework développé par Google qui rend le développement d'application mobile extrêmement simple. La plupart des gens en entendent parler par le Google/IO et la sortie de la version 2.0, mais dans mon cas, c'est grâce à Poka qui l'a choisi pour le développement de Ǧecko. Je l'ai regardé faire et ça m'a donné envie d'essayer sur un petit projet perso pour tout faire de A à Z.

Environnement de developpement

Je travaille habituellement sur vscodium, qui dispose d'extensions Flutter et Dart. Je recommande une installation de Flutter autonome plutôt que via les paquets système (https://flutter.dev/docs/get-started/install). Pour la machine virtuelle qui facilite grandement le développement, j'ai fait une concession sur mes habitudes et ai installé Android Studio via le snap. C'est sûrement la partie la plus pénible de tout le processus, et il faut prévoir au moins 20 Go de place disque libre. Une fois tout ça installé, et une appli de démo générée avec flutter create, Ctrl+F5 dans une fenêtre de code démarre automatiquement l'application en mode "hot reload", ce qui signifique que tout changement dans le code est immédiatement compilé et répercuté dans la machine virtuelle. C'est magique et accélère considérablement les allers-retours fréquents nécessaires au développement d'une interface graphique.

Mini projet

Quand on apprend n'importe quel langage informatique, il est bien de commencer avec un petit projet personnel d'ambition limitée mais qui permet de confronter une idée à la réalité de la programmation. Contrairement à Rust ou Julia, je ne recommande pas la lecture d'un livre avant de commencer, il suffit de programmer directement et de se poser les questions au fur et à mesure. Le Dart est un langage orienté objet très classique qui m'a beaucoup fait penser au C# et qui devrait être naturel pour n'importe qui ayant déjà l'habitude de la POO.

Dans mon cas, étant entouré de personnes jouant à PokémonGo, j'avais envie de faire une appli ludique pour trier les "bons" et les "mauvais" pokémons sur des critères totalement subjectifs. J'ai donc commencé par écrire un petit scrapper en Julia pour récupérer toutes les images de pokémon et leurs noms.

using HTTP, Gumbo

struct Pokémon
    numéro::Int
    nom::String
    génération::Int
end

padint(n) = lpad(string(n), 3, "0")

# get pokemon list in webpage

r = HTTP.get("https://www.pokemontrash.com/pokedex/liste-pokemon.php")
r_parsed = parsehtml(String(r.body))

pokedex_list = r_parsed.root[2][1][1][1][1][2][1][1][3]

pokémon_list = Vector{Pokémon}()

for (i,gen) = enumerate(7:-1:1)
    gen_list = pokedex_list[2*i][1]
    for row in gen_list.children
        numéro = parse(Int, row[1][1].text)
        nom = row[3][1][1][1].text
        pokemon = Pokémon(numéro, nom, gen)
        push!(pokémon_list, pokemon)
    end
end

sort!(pokémon_list, by=x->x.numéro)

# print to file

open("noms.txt", "w") do io
    write(io, join(map(x->x.nom, pokémon_list), "\n"))
end

# fetch images (fail for 795 and 802)

mkdir("img")

for pokémon in pokémon_list
    num = padint(pokémon.numéro)
    r = HTTP.get("https://www.pokemontrash.com/pokedex/images/sugimori/$num.png")
    println("img $num")
    open("img/$num.png", "w") do io
        write(io, r.body)
    end
end

Ceci fait, j'ai entrepris d'afficher une image à l'écran sur l'app, ce qui se fait très simplement en insérant le widget Image dans l'arbre de widget.

Image.asset("assets/pokemon/000.png")

Et me voilà avec une image de Bulbizarre à l'écran ! Pour la suite, je ne vais pas tout détailler, mais vous avez l'historique disponible sur mon Git. En gros, ça a été extrêmement simple, j'ai juste dû apprendre un à un les concepts de Flutter au moment où j'en avais besoin :

  • comment afficher une liste d'image → PageView
  • comment les rendre déplaçables avec le doigt → Draggable
  • comment faire des animations → TweenAnimationBuilder
  • comment structurer mon projet et faire communiquer les parties → StreamController
  • comment partager des données dans différentes parties de l'application → Provider
  • comment persister des données entre deux utilisations → lecture et écriture dans le système de fichier

À chaque question que je me suis posé, la documentation Flutter y répondait avec des pages très claires accompagnées de courtes vidéos didactiques. Et quand est arrivé le moment de faire tester l'application à d'autres personnes, il m'a suffi de lancer une ligne de commande.

flutter build apk --release # pour la release APK (Android)
flutter build web --release # pour la release Web

Voilà donc les livrables du projet si vous voulez les essayer.

Version web de l'application nécessitant JavaScript (un seul petit bug : Bulbizarre s'appelle "null" au début). Vous pouvez télécharger l'APK depuis le lien disponible sur la page de release.

Je ne sais pas si j'aurai envie de consacrer plus de temps à pokéswipe par la suite, parce que je pense plutôt travailler sur Ğecko dont l'utilité est plus évidente, mais j'ai beaucoup apprécié les quatre jours que j'ai passé à apprendre Dart/Flutter sur ce petit projet !

Conclusion

L'apprentissage de Dart/Flutter simple pourvu que l'on connaisse un langage orienté objet, en partie grâce à une excellente documentation. Le framework et l'environnement de développement permettent d'échafauder très rapidement une preuve de concept publiable facilement sous forme d'APK. Ce sera désormais mon choix n°1 pour le développement de toute interface graphique non triviale (c'est-à-dire qui ne tient pas en une page html/vuejs de moins de 1000 lignes de code).