Présentation technique de l’app android KMLkApp

Préambule

Il y a quelques années, j’avais développé quelques petites apps android avec Apache Cordova et HTML/CSS/JavaScript. Ici, pour KMLkApp, j’ai hésité entre Java, Kotlin et Flutter. J’ai opté pour Flutter par curiosté. A ce stade du développement, je n’arrive toujours pas à dire si je veux continuer avec Flutter ou réaliser ma prochaine app android avec un autre langage.

Librairies utilisés

Pour les quelques fonctionnalités de KMLkApp, il faut ajouter les librairies suivantes:

Disséquons le code

Le code source est disponible sur mon repository Codeberg.

Fichier colors.dart

Ce fichier contient les codes couleurs qui seront utilisés pour les différents éléments de l’app. J’ai repris les mêmes couleurs que le site KMLk.ch.

Fichier kmlk_db.dart

Cette classe (KmlkDb) permet de faire le lien entre la base de données SqLite et l’app. Dans KMLkApp, le modèle de données est monstre simple puisqu’il n’y a qu’une seule table.

On trouve cinq méthodes: deux pour gérer la base elle-même et trois pour accèder aux données.

Méthode db()

Ici on cherche à retourner une connexion à la base. La particularité de cette fonction est qu’elle gère la création et la migration de la base. En effet, on ouvre la base en indiquant un numéro de version. Si cette version de la base est introuvable, on lance la méthode de création ou migration.

Méthode createTables()

Cette fonction va créer la table au sein de la base. Comme ici c’est la première version de la base, la méthode est franchement simple.

Cette méthode a pour but de retourner les liens disponible. Il n’y a rien de compliqué: on obtient la connexion à la base puis on effectue une query sur la seule table de l’app (via db.query(_tableLink, orderBy: "id")).

Ici on ajoute un lien en base. Après avoir obtenu la connexion à la base, on prépare un bloc JSON avec l’identifiant et le lien à sauver. Puis on effectue une insertion (via db.insert(_tableLink, data, conflictAlgorithm: sql.ConflictAlgorithm.replace) ).

Rien de complexe non plus afin d’effacer un lien: on obtient éa connexion à la base puis on réalise une suppression (via db.delete(_tableLink, where: 'id = ?', whereArgs: [ id ])).

Fichier kmlk_home_page.dart

Cette classe représente la page principale de l’app. Elle affiche la liste des liens, le bouton pour scanner et l’onglet d’informations.

Méthode initState

Cette fonction est appelée lors de la création du composant. Dans la page principale, elle permet d’initialiser un objet de type PackageInfo, qui permettra de récupérer le numéro de version de l’app.

Méthode build

C’est la méthode principale de chaque composant (ou widget). Elle permet de piloter l’affichage des éléments du composant et ses dépendances. Dans la page principale, il y a le Drawer qui affiche l’onglet d’informations, l’AppBar qui affiche le titre et les boutons pour scanner et afficher l’onglet d’informations. Enfin, on trouve le Body qui affichera la liste des liens.

Par souci de lisibilité, j’ai déplacé le code de création de ces éléments dans chaque classe. Avant le return Scaffold, j’initialise les trois composants utilisés dans la page:

    
1qrScanner = KmlkQrScanner(ctx);
2tabLinks = KmlkTabLinks(ctx);
3tabAbout = KmlkTabAbout(ctx, _packageInfo.version);

Ensuite, dans le Scaffold, j’utilise

  • tabAbout.getTab() pour ajouter le contenu au Drawer.
  • qrScanner.getSmallButton() pour ajouter le bouton de scan à l’AppBar
  • tabLinks.getTab() pour ajouter la liste des liens au Body.

Il s’agit d’une classe (KmlkLinkRefreshEvent) vide (oui oui) dont l’objectif est de fournir un nom d’évènement utilisable pour permettre la communication entre composants.

Fichier kmlk_list_links.dart

Ce widget (KmlkListLinks) est reponsable d’afficher la liste des liens. Cette liste possède la particularité d’avoir un lien cliquable et un tiroir à actions (partager et effacer). Le point important de ce componsant est qu’il doit réagir à une mise jour depuis le bouton de scan présent dans la page principale.

Design d’une ligne de la liste

On utilise un widget ListView qui reçoit principalement deux éléments:

  • la liste des liens (variable _links, dont le contenu sera mis à jour)
  • un widget itemBuilder dont le rôle est d’afficher chaque élément de liste. Ici on utilise plusieurs composants:
    • un widget ListTile qui affiche le lien et supporte l’action d’ouverture du lien
    • un widget ActionPane placé à droite du lien et qui gère les actions “Partager” et “Effacer”

Mise à jour de a liste des liens

  • La méthode _refreshLinks obtient la liste des liens puis met à jour le widget via la mèthode setState.
  • Dans la méthode initState, on utilise un abonnement à l’évènement KmlkLinkRefreshEvent pour rèagir aux mises à jour extérieures. Lorsque le widget reçoit cet évènement, il lance la méthode _refreshLinks.

Partage d’un lien

Ici, grâce au plugin “flutter_share”, la méthode _shareLink déclenche l’affichage de la fonction de partage standard d’android.

Fichier kmlk_qr_scanner.dart

Cette classe (KmlkQrScanner) n’est pas un widget mais elle fournit un certain nombre d’éléments utiles à l’interface:

  • le pictogramme du bouton de scan pour la page principale
  • une snackbar pour afficher un message d’information ou d’erreur après le scan
  • la modale permettant de scanner un code QR

Cette méthode effectue une action particulière, en plus de sauver le lien contenu dans le code QR scanné: elle informe le widget kmlk_list_links qu’un nouveau lien a été ajouté et que la liste doit être mise à jour (FlutterBus.publish(KmlkLinkRefreshEvent());).

Fichier kmlk_tab_about.dart

Ce widget (KmlkTabAbout) est vraiment basique puisqu’il se contente d’afficher la présentattion de l’app.

Fichier kmlk_tab_links.dart

Ce widget (KmlkTabLinks) est responsable d’afficher la liste des liens. Il construit une liste scrollable dont le contenu est donné par kmlk_list_links.

Fichier main.dart

C’est le widget (KmlkApp) par lequel l’app démarre. Il affiche directement le widget KmlkHomePage

Liens