0% ont trouvé ce document utile (0 vote)
424 vues123 pages

Développement Mobile avec Flutter

Le document présente Flutter, un framework de développement mobile utilisant le langage Dart, qui permet de créer des applications natives avec une interface utilisateur adaptée aux plateformes Android et iOS. Il aborde les spécificités de Flutter, les types de widgets, ainsi que les différences entre StatelessWidget et StatefulWidget, tout en fournissant des exemples d'exercices pratiques. Enfin, il souligne l'importance du respect des principes de Material Design pour garantir une expérience utilisateur cohérente.

Transféré par

stephane
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
424 vues123 pages

Développement Mobile avec Flutter

Le document présente Flutter, un framework de développement mobile utilisant le langage Dart, qui permet de créer des applications natives avec une interface utilisateur adaptée aux plateformes Android et iOS. Il aborde les spécificités de Flutter, les types de widgets, ainsi que les différences entre StatelessWidget et StatefulWidget, tout en fournissant des exemples d'exercices pratiques. Enfin, il souligne l'importance du respect des principes de Material Design pour garantir une expérience utilisateur cohérente.

Transféré par

stephane
Copyright
© © All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

Flutter

Développement mobile
Développement mobile

Le marché des smartphones et appareils mobiles représentant une forte
valeur, les GAFAM ont mis à la disposition des développeurs de nombreux
outils et langages.

Les langages existants
– Android : Java puis Kotlin
– Apple : objective-c puis swift

Des langages et frameworks multiplateformes sont ensuite apparus
– ionic
– xamarin
Les langages

Le souci de Ionic et Xamarin est qu'ils ne fournissent pas une application
native
– le rendu de l'application peut être éloigné des standards de la
plateforme cible (Apple ou Android)
– Les applications sont plus lourdes
– L'accès aux capteurs du smartphone peut être limité

Nouvelles technologies
– React Native
– Flutter
Les langages

React Native
– React Native utilise le langage javascript. Il est donc plus familier pour
certains développeurs
– Les performances peuvent être décevantes

Flutter
– Look & Feel adaptés à la plateforme cible (Les widgets adoptent l'UI
Android ou Apple selon la cible)
– Performances élevés (application réactive)
– Taille d'applications moins importante qu'avec React Native
Flutter

Flutter utilise le langage Dart en ajoutant la notion de widget

Les widgets sont les éléments de l'interface (UI) comme les boutons, les icônes,
les champs de formulaire,…

Chaque widget est responsable de son rendu et de son comportement ←
indépendance forte

On peut combinés des widgets entre-eux pour en faire un widget composé

Syntaxe proche du C, javascript,…


Quelques spécificités
– Paramètres nommés
– Type générique
– async
Ecosystème Flutter

Un IDE : Android Studio

Un langage performant : Dart

Des extensions (+5000) : pubdev

Widgets : Documentation avec exemples, Liste des widgets

Inspection et debogage : DevTools

Publication des applications mobiles : Google Play Console

Accès natif aux capteurs du smartphone : Sensors

Accès à l'écosystème Google : Maps, Firebase (BDD, Authentification,
messagerie, crashlytics, ...)
Flutter – paramètres nommés

POO "classique"
– Constructeur : Center(Key key, double widthFactor) {...}
– Instanciation : Center('a7befd784', 7.6)

Sous Flutter, tous les paramètres des widgets sont nommés
– Constructeur : Center({Key? key, double? widthFactor}) {...}
– Instanciation : Center(widthFactor: 7.6)
Android Studio
Paramétrage JVM

Augmenter la RAM disponible
pour la JVM peut permettre
d'améliorer la vitesse
Dart
Dart - Particularités

Constructeurs
– Dart permet d'avoir des constructeurs qui ne prennent pas le nom de la
classe
– factory : copyWith, from,...

Opérateur flèche (arrow operator, lambda function)
– L'opérateur => est utilisé lorsqu'une méthode n'est constitué que d'une
seule instruction qui peut retourner une valeur
int sum(int num1, int num2) => num1 + num2;
– Equivalent à int sum(int num1, int num2) {return num1+num2;}
Exercice - Mastermind

L'ordinateur choisit un nombre entre 1000 et 9999. Vous devez trouver le
chiffre choisit avec le moins de coup possible

Si vous trouvez un chiffre mais au mauvais endroit, le programme répond
bull

Si vous trouvez un chiffre au bon endroit, le programme répond cow

Indiquez le nombre d'essai et le nombre de bulls et cows


Voir random, stdout et [Link]
Exercice - birthday

Faire une liste (tableau) contenant le nom et la date de naissance
d'informaticien célèbre

Afficher la liste connu

Lorsque l'utilisateur tape le nom d'une personne, la date de naissance est
affichée
Collections Dart
Collections

Pour typer les informations stockées dans les collections, Dart utilise les
types génériques <T>

Il existe un grand nombre de collections
– Set : collection non ordonnée d'éléments unique
– Queue : Liste FIFO
– Stack : pile FIFO
– List : équivalent d'un tableau
– Map : dictionnaire clé=>valeur

Un grand nombre d'opérations sont disponible pour ces collections
– itération (for), generate, contains, add, remove, ...

List et Map : Collections les plus utilisées en Flutter

Les tableaux = List
– List<int> numbers = [1, 2, 3, 4];
– print(numbers[0]) ;

Les tableaux associatifs = Map
– Map<String, int> ages = {"Lucas" : 20, "Leo" : 22};
– print(Map["Lucas"]) ;

dynamic si le type peut être différent pour les éléments stockés
– Map<String, dynamic> json = {"nom" :"Lucas", age:20};
Exercice

Soit deux listes
– listeA : 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89
– listeB : 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13

Ecrire un programme qui retourne la liste qui contient les éléments
communs à listeA et listeB (sans les duplicats)


Voir List, Set, for (ou forEach)
Exercice

Créez une classe Student (nom, prénom, age)
– L'âge est optionnel

Créez une constructeur paramétré

Créez un constructeur nommé (fromJson)

Les instances de l'objet Student seront mis dans une liste

Une boucle for sera utilisé pour afficher la liste des étudiants dans la
console
StatelessWidget et StatefulWidget

StatelessWidget StatefulWidget


un StatelessWidget est un widget ●
un StatefulWidget est un widget
immuable mutable

Les éléments visuels sont définis

Il peut être modifié dynamiquement
en réponse à des interactions
à l'instanciation utilisateur, des évènements, ...

Pas de mémoire pour stocker un ●
Il est composé de deux classes
état – StatefulWidget
– un état (State)
Création d'un projet Flutter

Fichier -> New -> New Flutter Project...

Flutter permet de créer des applications natives Linux, Windows, MacOS,
Andoid, iPhone, Application Web

Créer un Mobile virtuel
– Tools->Device Manager

Activer le mode développeur d'un smartphone
– [Link]
ceder-au-mode-developpeur-sur-android
Device Manager
StatelessWidget
StatefulWidget – Le widget
StatefulWidget – gestion de l'état
Flutter

Les widgets permettent de respecter le Material Design introduit par
Google. Pour les applications (mobile, web, desktop), l'utilisateur retrouvera
une uniformité d'usage dans les applications.

Quelques principes de bases du Material Design
– Hiérarchie visuelle pour indiquer l'importance relative des éléments
– Animations légères pour le dynamisme de l'application lors des
transitions
– Icônes et images claires

Une application qui s'éloigne trop des concepts UI/UX de Google peut être
refusée lors de la demande d'ajout au store
Widgets

Les widgets sont divisés en deux catégories principales : les widgets de
base et les widgets composites.

Les widgets de base sont des éléments simples qui peuvent être utilisés
tels quels ou combinés pour créer des interfaces utilisateur plus complexes.
– Ces widgets sont utilisés pour définir des éléments visuels de base dans l'interface utilisateur. Ils
sont souvent les briques de construction de base pour créer des mises en page et des éléments
d'interface.

Les widgets composites sont des widgets qui regroupent plusieurs widgets
de base ou d'autres widgets composites pour créer des structures plus
complexes.
– Ces widgets sont utilisés pour structurer l'application, définir la disposition globale, et regrouper
des éléments d'interface utilisateur pour créer des composants réutilisables et organisés.
Widget de Base
Widget de base

Widget de Mise en page ●
Widget d'Affichage
– Container – Text
– Row – RichText
– Column – Image
– ListView – Icon
– GridView
– Stack
– Center
Widget de base

Widget de Saisie ●
Widget d'Affichage de Contenu
– TextField – Card
– Checkbox – Tooltip
– Radio – Divider
– Switch – Expanded
– Slider – Spacer
– DropdownButton – SizedBox
Widgets Composites
Widgets Composites

Widgets de Navigation ●
Widgets de Dialogue
– AppBar – AlertDialog
– BottomNavigationBar – SimpleDialog
– Drawer – BottomSheet
– TabBar

Widgets d'Ecran ●
Widgets de Défilement
– Scaffold – SingleChildScrollView
– TabBarView – ListView
– NestedScrollView – GridView
Widgets Composites

Widgets de Formulaires ●
Widgets de Gestion de l'Etat
– Form – StatefulWidget
– FormField – StatelessWidget
– TextFormField – InheritedWidget
– State

Widgets d'Animation
– Provider
– AnimatedContainer
– Hero
– TweenAnimationBuilder
Widgets

Cette liste n'est pas exhaustive

Il est possible de créer des widgets personnalisés en combinant des
widgets de base et composite existants.
MaterialApp - La fondation

void main() => runApp(__widget__);

Pour __widget__, utiliser un widget Text()
MaterialApp - La fondation

Pour une application disposant d'un menu, d'un système de navigation
(routeur), d'un thème personnalisable, le widget de base sera souvent le ou
Scaffold Widget MaterialApp ou Scaffold
Première application

Le dossier lib contient les fichiers de notre application

Choisissez une plateforme cible
– Pour les ordinateurs peu puissants, évitez
l'émulateur mobile.

Lancer l'application
– Android Studio : Run
– VS Code : En ligne de commande -> Flutter run

Les applications Flutter supporte le hot reload
Analyse du code

import : déclaration des fichiers utilisés par
l'application
– flutter/[Link] permet d'utiliser les
widgets de base

main

class MyApp
– La classe MyApp dérive d'un
StatelessWidget
– Un StatelessWidget est un widget qui
ne changera pas d'aspect graphique
pendant la vie de l'application
L'arbre des widgets
Utilisation de l'inspecteur

On peut modifier certains paramètres
depuis l'inspecteur qui seront visibles dans
l'application


Exemple
– Cliquez sur Column
– Modifiez l'espacement entre les widgets
présents dans la colonne
Analyse du code

La méthode build est obligatoire et permet au widget de s'afficher

L'objet MaterialApp est l'infrastructure de base. Il fournit
– Une barre de navigation
– Un gestionnaire de route
– Un Thème
– Un ancr age pour afficher les éléments graphiques (home)
Analyse de code

La classe MyHomePage est un StatefulWidget. Cela signifie qu'il contient
des éléments graphiques et/ou des données qui pourront changer pendant
la vie de l'application

Le widget contient une méthode createState() obligatoire. Cette méthode
createState() renvoie une instance qui construit le widget à modifier
(MyHomePageState)

La classe MyHomePageState stocke les éléments qui permettent de
modifier la page

Sur un StatefulWidget, c'est la méthode setState() qui informe le widget qu'il
doit se redessiner
Exercice

Reprendre le code de l'application en séparant la déclaration des deux
objets Stateful et Stateless dans deux fichiers différents.

Remplacer le Widget Column par un Widget Row

Ajouter un Widget Expanded entre les 2 textes

Remplacer le Widget Center par un Widget Container

Rajouter une marge au Container

Faire apparaître le texte en haut de l'écran

Déployer le projet sur un dépôt git
Première Application

Créer une Listview dans l'application en modifiant le code par défaut
ListView "statique"

Dans une ListView statique, on connaît à l'avance le nombre d'éléments
présent dans la liste (exemple : un menu)

Dans le projet, ajoutez un ListView

On modifie le style de cet item

Exercice : modifier ensuite la
police et la taille du texte


children est un tableau avec
la liste des items de la
ListView
ListView "statique"

Ajouter un ListTile dans la liste des éléments de la ListView


Problème !
– L'application affiche un message d'erreur sur le fait que l'élément ne
peut pas être ajouté.
– Dans l'arbre des widgets, il faut un objet dérivé de Material pour que les
enfants sachent comment et ou se dessiner
– Dérivé de Material :

Card, Dialog, Drawer, Scaffold, MaterialApp
– => Englober la ListView dans une instance de Scaffold
ListView "statique"


Exercice :
– Ajouter un avatar (un
texte) dans un cercle,
une icône et sous-titre
aux ListTile
Listview "dynamique"

Pour une listview dynamique, on ne connaît pas le nombre d'éléments
constitutifs initiaux la liste pourrait provenir d'une API ou d'un système
extérieur)

On utilise un Builder dans un state pour alimenter les éléments de la
listview

Créer une application permettant d'afficher une liste dont les items seront
une Liste des étudiants

Dans l'exemple, il n'est pas nécessaire d'utiliser un StatefulWidget. Dans
une véritable application, les items pourraient être retrouvés depuis une
API. Le StatefulWidget serait alors plus adapté.

Modifier la structure de données pour associé à chaque étudiant une
couleur.
Les assets

Les assets sont des fichiers statiques que l'on embarque dans l'application.
Les assets les plus courants sont :
– les images
– des polices de caractères
– des textes
– des fichiers json

Par convention, les assets sont ajoutées dans le dossier assets du projet

Par convention, le dossier assets se trouve à la racine du projet
Exercice

Ajoutez une image sur la page de l'application en cours
Les assets

Attention aux chemins et à bien déclarer le fichier
Widgets

Manipulation de quelques widgets


Container

Le container est un simple bloc rectangulaire qui peut contenir un enfant.

On peut lui spécifier un margin et un padding

On peut lui spécifier sa hauteur et sa largeur.

Il tente toujours de se contraindre à prendre le minimum de place tout en
contenant son enfant

Exercice : Faire un conteneur rouge au centre de la page avec le texte
"Containeur"

Spécifier une largeur (width) de 100 puis de 1000
Drawer

Le widget Drawer permet d'ajouter un menu qui s'affiche suite à un clic sur
le menu "burger" de l'appBar

L'icône du menu burger est géré par le Drawer.
– Dans le Drawer, on ajoute généralement

un DrawerHeader : en-tête de menu

une ListView qui contiendra les différents menus


Exercice : Créez un Drawer en ajoutant votre avatar généré sur [Link]
[Link]/#generateur qui sera dans un ovale
Exercice : Widget personnalisé

Créer un widget ayant les bords arrondi (Card) contenant un texte et deux
boutons en dessous du texte

Ajouter ce widget dans la ListView (15 items)
Polices et ThemeData

Flutter gère les polices .ttf (True Type Fonts) et .otf (Open Type Fonts)

ttf
– Plus légère
– Généralement plusieurs fichiers selon le style (regular, bold, italic)

otf
– Gère des fonctionnalités avancées (glyphe alternatives pour certains
caractères, ligature complexes, caractères spéciaux)

Google met à disposition une grande quantité de polices
Polices et ThemeData

Style de police
– Serif : Elles ont un empattement à la fin des caractères. Cela guide l’œil
pour les caractères suivants. Important pour les textes imprimés (Times)
– Sans-serif : Pas d'empattement. Ligne plus nette et moderne. Plus
lisible à l'écran (Arial)
– Monospace : Chasse fixe. Tous les caractères occupent la même largeur
(Console)
– Display : Stylisées et décoratives (Pour les titres par exemple) (Lobster)
– Symbol : Les caractères sont des icones ou pictogrammes (Webdings)
– Script : Imite l'écriture humaine
– ......

Sur le site Google Fonts, Télécharger la police Tangerine

Dézipper le fichier dans le dossier assets/fonts/ du projet

Mettre à jour le fichier [Link]

Modifié la propriété style du texte

Si on utilise le même style sur plusieurs pages, il est préférable d'utiliser le
ThemeData ou des Widgets personnalisé que l'on aura stylisé

ThemeData
– ThemeData dispose de plusieurs propriétés que l'on peut ensuite
passer en argument lorsqu'on l'instancie

Widget personnalisé

Navigation
La navigation

La navigation est gérée par deux API
– Navigator
– Router

Le navigateur garde la pile des appels des pages et du contexte associée.
On peut alors utiliser le bouton "Retour" du smartphone.

Nous verrons deux systèmes de navigation. Pour en savoir plus, voir la
page medium qui détaille bien les différentes routes.
Navigation

Un objet Navigator est instancié par les descendants de MaterialApp
(Scaffold, Drawer,...). Il peut être utilisé par tous les Widgets de l'arbre
descendant

Pour que le widget puisse proposer une interaction de changement de page
avec l'utilisateur, il doit disposer d'une propriété
– onTap, onPressed
– onDoubleTap
– onLongPressed

Les widgets qui disposent de ces propriétés sont :
– Les boutons (TextButton, ElevatedButton,...)
– ListTile (ListTile, ExpansionTile,...)
Navigation

Si le widget ne dispose pas d'une des propriétés pouvant réagir à
l'interaction de l'utilisateur, on peut lui adjoindre un widget InkWell ou
l'englober dans un widget GestureDetector.

InkWell rajoute un retour visuel à l'utilisateur sous la forme d'une vague
colorée qui parcourt le widget

GestureDetector ne fait pas de retour visuel mais permet de gérer plus
finement l'interaction (par exemple glisser/déposer)
Navigator
Navigator

Ajouter ce code sur un widget ListTile de la ListView


En exercice
– Déplacez la page présente dans [Link] dans le dossier screens
– Essayez de comprendre le code de la propriété onTap (fonction
anonyme)

Navigator

La méthode push du navigateur prend en paramètre la page (un widget)
vers lequel il faut rediriger l'utilisateur lorsqu'il interagit avec le widget

Pour tester la navigation, il faut créer de nouvelles pages.
– Créer un dossier screens sous lib
– Ajouter un statelessWidget dans ce dossier (Nommer par exemple
Page2) qui va afficher un Text dans un Widget Center
– importer [Link] dans le [Link]
Router
La navigation

Les routes nommées

Pour les routes nommées, elles sont définies à travers la donnée membre
routes du Widget de base Application


Pour chaque route, on indique la page qui doit s'afficher. La page est une
instance d'une classe dérivée de Stateless ou Stateful widget
La navigation

Les routes nommées sont très utiles, simples et proche d'une navigation sur
Internet

Pour de grands projets (beaucoup de routes, la gestion peut devenir
complexe), Les routes nommées sont moins adaptées

Lorsque les états des différentes pages sont complexes, l'utilisation des
routes est déconseillée. Il faut mettre en place un mécanisme de gestion de
l'état
Asynchrone
Méthode Asynchrone

Les méthodes asynchrones permettent d'indiquer au système qu'une
opération va être longue et qu'il peut reprendre la main pour faire d'autres
opérations.

Opérations longues
– Accès à la base de données locale
– Lecture de fichiers locaux (assets)
– Accès à un serveur distant

Flutter permet également d'afficher un widget en attendant la réponse
Future, await, async

L'état du widget change (no data -> data). Un statefulwidget est donc utilisé.

FutureBuilder prend deux arguments obligatoire
– future : une fonction asynchrone qui renseignera une variable
[Link] lorsque les données seront disponible.
– builder : le builder pourra examiner le snapshot pour savoir si les
données ont été reçues
Future, await, async
http

Ajoutez le package http au projet
En production, , il est nécessaire d'ajouter les permissions pour autoriser le
smartphone à accéder à Internet
– Android : Fichier android->src->main

– iOS : Les appels vers un serveur https est autorisé par défaut
Communication serveur
http

Utilisation de l'API : [Link]

Créez le modèle Album

Ajoutez un constructeur nommé pour Album pour la dé-sérialisation json

Ajoutez le gestionnaire d'état d'un statefulWidget qui affichera le json sur la
page (dans un widget Center)


Désérialisez le json en un objet Album

Affichez le title de l'album obtenu
Base de données locales
Local storage

Il est parfois nécessaire de stocker de données sur le smartphone

On peut stocker les données dans une base sharedPreferences ou SQLite

SharedPreferences
– Léger
– Stockage clé/valeur

SQLite
– Base de données relationnelle
– Moteur SQL de plusieurs Ko
Local storage

Les fonctionnalités de SQLite sont apportées par un package externe qu'il
faut ajouter au projet. SQLite a également besoin du package path


Cette commande ajoute les informations sur le package importé dans le
fichier [Link]
semver

La gestion sémantique des versions est un standard pour tous les langages
de développement (PHP, Typescript, Python, Flutter,...)

Il est nécessaire de garder une trace des versions compatibles des
packages utilisés dans un projet.

semver se base sur 3 chiffres qui définissent une version
– [Link]

Lorsqu'on publie une nouvelle version, on incrémente un des numéros de la
version

On incrémente le numéro de version suivant cette politique
– le numéro de version MAJEUR quand il y a des changements non
rétrocompatibles,
– le numéro de version MINEUR quand il y a des ajouts de fonctionnalités
rétrocompatibles,
– le numéro de version de CORRECTIF quand il y a des corrections
d’anomalies rétrocompatibles.
semver

Signification des signes
– ^ Utilisé pour indiquer une plage de versions compatibles dans la
même série de modifications (même majeure)
– >= Indique une dépendance avec une version égale ou supérieure à la
version spécifiée tout en conservant la majeure
– <= Indique une dépendance avec une version strictement inférieure à la
version spécifiée.
– < : Indique une dépendance avec une version strictement inférieure à la
version spécifiée.
– > : Indique une dépendance avec une version strictement supérieure à
la version spécifiée.
Local storage

On veut stocker le nom et prénom des utilisateurs qui pourront entrer ces
informations sur un formulaire (Dans une application réelle, l'application se
connecterait à un serveur distant – voir pages suivantes API)

Créer un dossier models dans lib

Créer un fichier [Link] avec la classe User permettant de stocker les
informations

Ajouter une méthode toMap() à User
– Mapping de la database en un objet (au sens POO)

Ajouter une méthode toString()
– Permet la sérialisation pour l'affichage à l'écran
Local storage

Modifier le fichier [Link]

Requete

N° de version de
la base
Local storage

Si on doit modifier le schéma de la base de données, on peut ajouter la
propriété onUpgrade()
Local storage

Exercice :
– Créer une table locale sqlite avec un champ firstname et lastname
– Modifier la table locale en ajoutant un champ mail
– Afficher le numéro de version de votre table
Développement en couches & CRUD

Créer un dossier services sous lib

Créer une classe DatabaseService qui va ouvrir la base de données

Ajouter la méthode insert() sur la classe User

Appeler la fonction depuis le main

[Link]('INSERT INTO users(firstname, lastname, mail)
VALUES($firstname, $lastname, $mail');

DANGER
INJECTION SQL
Insert

Pour éviter les injections SQL

Utiliser les requêtes paramétrées
– [Link]('INSERT INTO users(firstname, lastname, mail)
VALUES( ?, ?,?)', [firstname, lastname, mail]) ;

Utiliser la méthode insert de sqflite qui prend en paramètre une
Map(colonne, value) pour insérer les données
– [Link]('users', [Link]()) ;

insert et update prennent un argument nommé
– conflictAlgorithm valant replace ou ignore
CRUD - CREATE
Formulaires
Formulaire - Graphique

Il existe un grand nombre de widgets pour interagir avec l'application
– Bouton : ElevatedButton, FilledButton, IconButton, ...
– Texte : TextFormField
– Valeur numérique : Slider
– Case à cocher : Radio, Checkbox
– Date : DatePicker, TimePicker
– ...

Les widgets de saisie sont généralement placés dans des (dérivés de)
StatefulWidget pour gérer leur état

Un globalKey est ajouté pour connaitre le Widget
Formulaire - Validation

Validation
– Il est possible de rajouter un validateur sur les données saisies par
l'utilisateur
Formulaire – Traiter la valeur saisie

La valeur saisie est stockée par un TextEditingController présent dans le
gestionnaire d'état (state) du StatefulWidget

Instanciation et destruction du TextEditingController
Formulaire – Traiter la valeur saisie

On indique la méthode qui sera chargée de traiter la valeur saisie lors de
l'initialisation de l'état


La méthode _storeText est une méthode du gestionnaire d'état qui permet
de manipuler la valeur saisie
Variable d'environnement
Environnement

Les urls et autres constantes doivent se trouver dans un fichier de
configuration (.env par convention)

Ce fichier n'est pas versionné et est différent selon le serveur sur lequel on
travaille (développement, intégration, production)

Ajouter le package dotenv et placer l'url de l'API dans ce fichier.
State Management
Gestion des états

La gestion des états consiste à maintenir les différents widgets
affichant de l'information en adéquation avec l'état actuel de
l'application

Comme pour les applications web réactive, l'objectif est de
faire en sorte que seuls les éléments (les widgets) qui doivent
changer se ré-affiche sans que les autres ne soient impactés
– Cela permet à l'application d'être plus réactive
– La page entière n'a pas à être réaffichée (gain en rapidité,
fluidité, consommation ressources diminuée)
Exemples

Conserver et afficher les choix et
préférences de l'utilisateur

Montrer Les informations de choix
sur plusieurs widgets

...
Gestion des états

Pour gérer les états de l'application (state management), beaucoup d''appro
ches différentes sont disponibles
– setState() : Solution bas niveau. Fonctionne très bien lorsque l'état reste
simple à gérer
– InheritedWidget : Permet de parcourir l'arbre des widgets pour
déterminer ceux qui sont impactés
– Redux : Implémentation proche de la bibliothèque redux du framework
React
– Bloc : Business Logic Component. Proche du MVVM (Le BloC remplace
le ViewModel
– GetIt : Plugin très complet qui apporte également d'autres
fonctionnalités. Utilise le design pattern Observer<->Listener
Gestion des états

Avantages des solutions mises en oeuvre
– Gestion centralisée des états (moins de bugs)
– Séparation des responsabilités (SRP)


Inconvénients
– Apprentissage complexe au départ
– Ajout de beaucoup de fichiers (inutile pour les états simples)
– Choix large et donc difficile à déterminer celui qui correspond le mieux à
l'application en développement
setState()

Dans la classe héritée de State, on définit une méthode appelant setState()


L'appel de setState force le widget à se recréer (et se ré-afficher)
setState()

Avantages
– Le plus simple à mettre en place
– Suffit pour les gestions simples d'états


Inconvénients
– La gestion des états est intégrée dans le widget
– Compliquer à maintenir (lorsqu'il y a une gestion d'état importante)
inheritedWidget

InheritedWidget est un widget particulier qui va stocker les données.
Lorsqu'une données est modifiée, il informe les widgets enfants qu'une
information a été modifiée. Ils ont alors la possibilité de se redessiner

Cet objet dérivé de InheritedWidget contient
les données de l'état qui vont varier

La fonction of est un constructeur static. Il
renvoie une instance de l'objet si elle existe
déjà ou en créé une
InheritedWidget

L'InheritedWidget doit etre le parent du
widget stateful qui sera modifiable.

Généralement, on met ce widget en tête
de l'arbre
InheritedWidget – Exercice 1

Modifier le code afin de porter plusieurs informations. Ajouter un container
et un second BottomFloatingButton

Le second FloatingButton permet de changer aléatoirement la couleur du
container

AppData portera les informations et le code permettant de gérer/modifier :
– le compteur
– la couleur du container
InheritedWidget – Exercice 2

Créer une application Flutter permettant de liker des films
– La liste des films est disponible sur [Link]

Utiliser l'API pour afficher la liste des films actuellement à l'affiche
– L'application dispose d'une liste de films, l'affiche du film et leur titre
(voir documentation)
– Lorsque l'utilisateur clique sur la vignette d'un film, le contour change
montrant que ce film est sélectionné. (un second clic le désélectionne)
– Un compteur dans la AppBar montre le nombre de films likés

Lorsque l'utilisateur revient sur l'application, il retrouve tous les films qu'il a
liké (la persistance se fait en local)
InheritedWidget – Exercice 2 - Informations

la documentation de l'API est disponible sur l'url
– [Link]

Liste des films à l'affiche
– [Link]
=1

Images
– [Link] de l'image}/{chemin de l'affiche}
– chemin de l'affiche

Donner dans la réponse de la liste des pages
– taille de l'image : w92, w154, w185, w342, w500, w780, original

exemple :[Link]
[Link]

Informations - Suite

Pour l'authentification, deux méthodes sont possibles :
– clé api_key en paramètre de l'url (&api_key=xxxxxxxxxx)
– Bearer token. Dans les appels, on ajoute des en-têtes pour la requete)
– 'Authorization' : 'Bearer eyzzzzzzzzzzzzzzzzzzzz'
Provider

Le gestionnaire d'état Provider utilise le concept de notifications de
changement (Change Notification). Cela permet de notifier les widgets qui
écoutent d'un changement de l'état.
Provider

Design Pattern Observer
Provider

On indique les providers qui sont ●
On créé la classe qui gère l'état
dans l'application
Provider

Le widget contenant le listener


Appel de la méthode qui fait le changement d'état
Gestion des états

Le dépôt [Link] décrit
les différents gestionnaires d'état utilisés par Flutter

Ce dépôt montre également l'implémentation les designs d'architectures
sous Flutter (MVC, MVU,...)
Capteurs
Accès aux capteurs

Les smartphones modernes disposent de plusieurs capteurs
– photos/vidéos
– accéléromètre
– baromètre (capteur de pression)
– GPS
– microphone
– Capteur d'empreintes digitales
– Capteur infrarouge
– Capteur d'humidité
– ....
Permissions

Les permissions sont nécessaires pour que l'appareil demande à
l'utilisateur s'il accepte que l'application puisse accéder à des capteurs,
accéder aux contacts, passer des appels,...

Les permissions sont ajoutées dans le manifest Android
– Fichier android/app/src/main/[Link]

Pour l'appareil photo, on ajoute 2 permissions :
– Demande à l'utilisateur d'utiliser la caméra
– Demande d'utiliser le matériel caméra du smartphone
Utiliser la caméra

minSdkVersion 21 (app/[Link])

Ajouter le package camera

Ajouter les packages path et path_provider (pour stocker les photos)

Ne fonctionne que sur smartphone/émulateur. Accès à l'appareil photo non
assuré sur les autres devices

Au démarrage de l'application, on recherche le nombre et les fonctionnalités
des caméras
Sur l'état, on initialise l'accès à l'appareil photo

sur le clic du bouton de la bottomBar, on prend une photo
Projet

Invitation sur le github hébergeant l'application API en Flutter

Sur l'application Flutter, vous devez avoir :
– un fichier [Link] qui explique ce que fait l'application. Si des
éléments particuliers sont nécessaires pour faire fonctionner
l'application, il faut l'indiquer
– Le package dotenv doit être utilisé

Le code doit être commenté et correctement formaté
Projet Flutter

Par groupe de 3 ou 4 personnes, l'objectif est de réaliser une application
pour un entraineur qui veut suivre l'entrainement du sportif à distance.

Le sportif en question est un boxeur. Les exercices attendus par l'entraineur
sont
– cross (sur terrain accidenté et sans connectivité mobile assurée)
– saut à la corde

Les entrainements sont journalisés. Il y a donc des données stockées par
journée d'entrainement

Projet Flutter

L'entraineur veut pouvoir avoir aux fonctionnalités suivantes
– Voir les parcours effectués par le sportif sur une carte
– Savoir le nombre de sauts effectués par le sportif pendant les séances
de saut à la corde
Projet Flutter

mettre le projet sur git et inviter l'utilisateur smartmoov
– Le [Link] contient les membres du groupe et toutes les
indications permettant de lancer le projet

Proposez des wireframes et maquettes à l'entraineur avant de démarrer le
développement

Développer d'abord une des fonctionnalités (suivi des saut/parcours cross)
– L'objectif est d'avoir un code propre et lisible

On se limitera à l'application du sportif

L'envoi des données collectées par l'application mobile vers un back-end ne
sera pas fait. Le format des données sera toutefois commenté et expliqué.
Projet Flutter

Note
– On fera l'application dédiée au sportif et non à l'entraineur
– Dans une application réelle, les données seront remontées vers un
serveur distant.

Vous aimerez peut-être aussi