Vous êtes sur la page 1sur 51

Atelier 1 : Les premières applications « Simples »

Si un développeur mobile a créé une application pour les appareils dont le système
d’exploitation est iOS (Iphone), cette application ne peut pas fonctionner sous des appareils
Android. De plus, si on a recréé la même application pour Android et par la suite nous voulons
apporter des changements à l’application. Il faut appliquer ces modifications deux fois : pour
iOS et pour Android.
Alors, l’inconvénient majeur dans ce cas sera la perte de temps et de ressources.
 La solution est : développer une application cross-plateformes ou multiplateforme.
Une application mobile multiplateforme est une application développée pour fonctionner sur
plusieurs systèmes d'exploitation mobiles, tels qu'Android et iOS, à l'aide d'un seul code source.
Les applications mobiles cross-plateformes peuvent être développées à l'aide de différents
framework ou technologies, tels que React Native, Flutter et autres.

La différence entre native et cross-plateforme

Il est vrai que nous utilisons des applications natives (WhatsApp, Spotify, …), des applications
cross-plateformes ou hybrides (Facebook, Instagram, Twitter, …) tous les jours, sans avoir
besoin de savoir ce qui se cache derrière ces termes.
Remarque : Les applications cross-platform ressemblent beaucoup aux applications hybrides.
Cependant, contrairement aux appli hybrides dont le code s'exécute dans un « webview » et
mobile, les applications cross-platform produisent des applications natives à l’aide d’un même
code source compilé.

Développement iOS natif

Pour les applications natives iOS, il existe deux langages de programmation native : Swift et
Objective-C
 Le développement natif iOS fait référence au codage d'une application dans le langage
de programmation natif pour iOS, qui est Swift. Les applications natives sont
généralement développées à partir de zéro et nécessitent une connaissance approfondie
du langage et des frameworks iOS. Cela peut être un bon choix si vous avez du temps
et des ressources à consacrer au développement de votre propre application, car cela
vous donne un contrôle total sur sa conception et ses fonctionnalités.
 Objective-C est un langage de programmation très populaire largement utilisé pour
développer des applications iOS. Il a été introduit pour la première fois par Apple au
début des années 1980 et est depuis devenu un langage de base pour le développement
d'applications iOS. Cependant, Objective-C présente également certains inconvénients.
Par exemple, le langage est très compliqué et peut être difficile à apprendre pour les
débutants. De plus, cela nécessite une grande quantité de mémoire, ce qui peut affecter
les performances globales de l'application.

1
Développement Android natif

Le développement Android natif implique de coder une application en Java ou en Kotlin….


Tout comme avec iOS, le développement natif nécessite une compréhension approfondie du
langage et des frameworks Android, il convient donc mieux aux développeurs expérimentés
disposant de beaucoup de temps et de ressources à consacrer au projet.

Point de Native Cross-platform


différence
Architecture Différentes applications Une application pour plusieurs systèmes
pour différentes d'exploitation, logiciels et appareils.
plateformes
Temps de Prend du temps Comparativement moins de temps
développement
Code- Presque aucun Plus de 60 % du code peut être réutilisé
Réutilisabilité

Les avantages du développement d'applications mobiles cross-plateformes

 Application mobile pour plusieurs platesformes : l'avantage le plus important de la


construction d’une application cross-plateforme est que le résultat du processus de
développement peut être utilisé sur plusieurs plates-formes. Cette approche est la mieux
adaptée lorsque les fonctionnalités commerciales sont simples et que l’objectif est de
réduire les délais de commercialisation.
 Coût de développement réduit : dans un scénario typique, un produit technologique
nécessitera trois flux de travail de développement distincts : Web, Android et iOS. Un
framework cross-plateforme peut réduire l’effort requis à moins de la moitié.
 Processus de développement agile : naturellement, le processus de développement
consommera moins d'heures humaines lorsqu'un seul code est utilisé. Et un
développement MVP (Minimum Viable Product ) avec un délai de mise sur le marché
réduit, grâce aux techniques de développement d'applications mobiles cross-
plateformes, le propriétaire de l'entreprise peut rapidement développer le produit
minimum viable (MVP) et le tester auprès d'un public plus large dans l'environnement
réel, recevoir rapidement des commentaires et travailler sur le mobile
 Maintenance et convivialité (Usability) du code plus simple : avoir un seul code pour
plusieurs plates-formes signifie que lorsque vient le temps d'ajouter ou de supprimer des
fonctionnalités de l'application, un seul ensemble de mises à jour suffit pour mettre à
jour l'application sur toutes les plates-formes.
 Touchez un plus grand nombre de clients : étant donné que l'équipe de développement
est capable de créer différentes applications mobiles pour différentes plates-formes
(appareils et systèmes d'exploitation) avec un seul code, le propriétaire de l'entreprise
peut lancer l'application mobile sur différentes plates-formes simultanément.
Ainsi, il serait en mesure d’atteindre et de répondre à une clientèle plus large. Sinon, si
les techniques de développement d’applications mobiles natives sont suivies, il faudrait
2
beaucoup plus de temps à une entreprise pour atteindre un large public rapidement et
efficacement.

React Native
Est un framework de développement d'applications open source cross-plateforme appartenant
à Meta (précédent Facebook). Il est utilisé pour créer des applications cross-plateformes natives
pour Android, iOS et Windows à l'aide de JavaScript et TypeScript (une version fortement typée
de JS).
Les applications populaires basées sur React Native : Instagram, Pinterest, et Tesla.

Flutter
Est un framework de développement d'applications multiplateformes open source appartenant
à Google. Il est utilisé pour créer des applications multiplateformes natives pour Android, iOS
et Windows à l'aide de Dart.
Quelques exemples sont Alibaba, BMW et Google Ads.

Flutter se base sur des composants déjà créé par les développeurs de Google. Ces composants
sont appelés Widgets.
Les widgets sont des éléments constitutifs d'une application Flutter. Ce sont des configurations
pour différentes parties de l'interface utilisateur. Les widgets peuvent être des éléments de
structuration, des éléments d'entrée, des mises en page d'interface utilisateur, des éléments
interactifs, des animations, des images, des icônes et des widgets personnalisés que vous pouvez
créer vous-même !
Lorsque nous composons des widgets ensemble, ils génèrent l'arborescence des widgets
« widget’s tree ». C'est similaire à la façon dont le DOM sur le navigateur génère une
arborescence. Tous les éléments montés qui sont rendus à l'écran présentenent l'arborescence
des éléments. Lorsque vous exécutez une application Flutter, la fonction principale appelle la
méthode runApp(). La fonction runApp() prend le widget donné et le rend la racine de
l'arborescence des widgets.
- Un widget est soit avec état, soit sans état. Si un widget peut changer (lorsqu’un
utilisateur interagit avec, par exemple), il est avec état « statefull Widget »
- Un widget sans état ne change jamais. Icon, IconButton et Text sont des exemples de
widgets sans état, StatelessWidget.
 On peut citer comme widgets : Row (ligne), Column (colonne), Padding (permet
d’avoir des espaces dans l’application), MaterialApp, Scaffold, Text, Card,
SafeZone,….
Conclusion : flutter nous permettons d’écrire un seul code qui sera appliqué à plusieurs
appareils. En effet, au lieu de programmer des applications iOS par Swift et des applications
Android et Web par Java et Javascript, avec flutter, il suffit d’écrire un code Dart. Dart est un
langage simple créé par Google. De plus, Dart a le même principe que les langages Java et
JavaScript. Ici, nous utilisons les widgets avec l’avantage d’accès au code source originale
puisque ce framework est open source.

3
1ére application : Créer une application avec une couleur en arrière-plan et
une image au centre
1. Créer un nouveau projet : soit en utilisant Powershell , soit sous le terminal de VSc et
écrire la commande suivante :
flutter create Nom_projet
PS : pour que l’appli sera créée convenablement, il faut s’assurer que vous êtes
connectés à l’ Internet.
2. Ouvrir le projet par VSc, le code est enregistré dans le dossier lib : le nom du fichier
est main.dart.
3. Pour exécuter le code, il faut ouvrir l’émulateur de téléphone.
- Ouvrir l’Android Studio. Si un projet est ouvert, fermez-le.
- Par la suite, sélectionner « Virtual Device Manager ».
- Ainsi, sélectionner l’appareil souhaité et la démarrez.

4
4. On peut maintenant exécuter le code soit par le terminal de VSc en écrivant flutter run
(il faut se localiser dans l’emplacement où se trouve le code sinon utilisez « cd »), soit
par l’utilisation du menu d’accueil « exécuter » et choisir « Exécuter sans débogage ».

5
Vous allez remarquer que le deuxième type d’exécution est plus rapide que le premier.
L’application par défaut permet d’incrémenter un entier par cliquant sur un bouton
« + ».
5. Supprimer le code écrit dans le fichier main.dart sauf les lignes suivantes :
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
Vous remarquez que le code « const MyApp()» est sélectionné par rouge puisque nous
avons supprimer le code de la fonction MyApp.
Maintenant, nous allons utiliser le composant MaterialApp créé par Google.

MaterialApp est une classe Flutter prédéfinie. Le composant principal de Flutter est
probablement celui-ci.
Alors, pourquoi utilisons-nous MaterialApp dans Flutter ?

MaterialApp est une extension de WidgetsApp de Flutter, un widget de base de niveau


supérieur (basic top-level widget). WidgetsApp est un widget pratique qui résume plusieurs
éléments requis pour la plupart des applications mobiles, tels que la configuration de la
navigation et l'application d'un thème à l'ensemble du programme.

Dans le MaterialApp, il faut utiliser l’attribut home qui prend comme paramètre un Widget.
Ecrire dans la méthode runapp le code suivant :
void main() {
runApp(MaterialApp(home: Text('hello world '),
),
) ;
}

(On remarque que le texte s’affiche au plus haut et au plus gauche de l’écran.) L’arbre de
notre application est la suivante :
6
Si on veut que le texte s’affiche au centre de l’écran, il faut utiliser le Widget center qui
est composé par un enfant (child). Ecrire alors le code suivant :
void main() {
runApp(MaterialApp(
home:
Center(
child: Text(
'hello world '
),
),
),
) ;
}

Remarque : text Widget est un enfant de center Widget.


Maintenant, nous utilisons le composant Scaffold Widget.

Scaffold Widget : permet d’ajouter des composants comme les boutons, les barres, les
images…
Alors, on veut ajouter un Bar qui contient du texte, de plus, nous voulons changer la couleur
du Bar. La création du Bar sera faite par le Widget AppBar. Le Widget AppBar sera l’enfant
du widget Scaffold. Ecrire le code suivant :
void main() {
runApp(MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('première application'),
backgroundColor: Colors.blue[900],

7
),
backgroundColor: Colors.blue,
),
),
) ;
}
Remarque : On peut modifier le degré de couleur par l’ajout [Valeur]. La valeur est entre 100
et 900.

Maintenant, on veut ajouter une image au centre de l’écran. Il existe un widget nommé Image
qui peut prend soit une image de l’internet, soit une image de votre répertoire.
Pour utiliser des images de votre PC, il faut :
1. Créer un dossier nommé « images » dans votre dossier de projet et qui contient les
images à utilisées.
2. Faire des modifications dans le fichier de configuration « pubspec.yaml ». Dans la
partie assets, supprimer le « # » qui représente un commentaire. De même pour les
lignes sous dessous. Ces lignes sont les chemins des images à utiliser. Modifier ces
derniers et enregistrer les modifications.
assets:
- images/
Remarque : on peut écrire le chemin complet de l’image à utiliser. Mais, si nous allons utiliser
plusieurs images, il faut écrire tous les chemins de ces images là. Ceci peut poser des
problèmes si on a un grand nombre d’images. La solution est d’écrire le chemin du dossier
seulement qui contient les images.
void main() {
runApp(MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('premier application'),
backgroundColor: Colors.blue[900],
),
backgroundColor: Colors.blue,
body: Image(image: AssetImage('images/figure1.jpg'),
),
),

8
),
) ;
}

On veut que l’image soit place au centre de l’écran.


void main() {
runApp(MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text(' application 1'),
backgroundColor: Colors.blue[900],
),
backgroundColor: Colors.blue,
body: Center(
child: Image(image: AssetImage('images/figure1.jpg'
),
),
),
),
),
) ;
}

9
Maintenant, on veut utiliser une image de l’internet. Aller sur google et écrire un nom
d’image. Par la suite cliquer sur le bouton droit et choisir « ouvrir image dans un nouvel
onglet » et ainsi copier l’URL. Ecrire le code suivant :
void main() {
runApp(MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text(' application 1'),
backgroundColor: Colors.blue[900],
),
backgroundColor: Colors.blue,
body: Center(
child: Image(image: NetworkImage('https://encrypted-
tbn0.gstatic.com/images?q=tbn:ANd9GcSwg2PWrY_5mkISXy_GqXWUYPbglvpL6FSUgg&usqp=
CAU')
),
),
),
),
) ;
}

10
L’arbre de cette application est le suivant :

11
2éme application : Créer une application Business Card

Notre deuxième application a la forme détaillée dans la figure sous dessus.


1. Créer un nouveau projet nommé app_2. Il faut que vous soyez dans le répertoire des
projets nommé cross_platform et écrire la commande suivante : flutter create app_2.
2. Ouvrir l’émulateur du téléphone.
3. Dans un premier temps, on va commencer par créer un MaterialApp widget dans le
main.dart qui contient home : un Scaffold Widget. Par la suite, on va changer dans le
Scaffold widget la couleur d’arrière-plan au bleu ciel avec le degré 700 et le body
contient un container (comme la balise <div>).
La classe container dans Flutter est un widget pratique qui combine la peinture (colorie),
le positionnement et le dimensionnement courants des widgets. Une classe Container peut
être utilisée pour stocker un ou plusieurs widgets et les positionner à l'écran selon notre
convenance. Fondamentalement, un container est comme une boîte dans laquelle on stocke
son contenu. Un élément conteneur de base qui stocke un widget a une marge qui sépare le
conteneur actuel des autres contenus. Le conteneur total peut recevoir une bordure de
différentes formes, par exemple des rectangles arrondis, etc. Un conteneur entoure son
enfant avec un remplissage, puis applique des contraintes supplémentaires à l'étendue
remplie (en incorporant la largeur et la hauteur « width et height » comme contraintes, si
l'une ou l'autre n'est pas nul).

12
void main() {
runApp(MaterialApp(
home: Scaffold(
backgroundColor: Colors.cyan[700],
body: Container(),
),
));
}

Remarque : utilisation de Hot Reload


Dans le code, on a utilisé la couleur bleu ciel comme couleur d’arrière-plan. Si on veut la
changer au couleur rouge.
void main() {
runApp(MaterialApp(
home: Scaffold(
backgroundColor: Colors.red,
body: Container(),
),
));
}
On remarque que le ré-fraichement du programme prend un peu de temps même si on a
appliqué des changements à une seule ligne du code. La solution est d’utiliser le bouton de
Hot reload. De plus, on remarque que même si les changements sont écrits dans le code
mais lorsque on applique le hot reload les changements ne seront pas pris en compte.
Alors pour utiliser ce bouton, il faut utiliser les widgets suivants : Stateless Widget ou
Stateful Widget.
Lorsque on écrit l’abréviation suivante stlss, le code du class Stateless Widget s’affiche
automatiquement.
class MyWidget extends StatelessWidget {
const MyWidget({super.key});

@override
Widget build(BuildContext context) {
return const Placeholder();
}
}

13
Supprimer le mot MyWidget et le remplacer par MyApp. Lorsque vous écrit le mot MyApp
après le mot class, « MyApp » sera écrit automatiquement après le mot const.
class MyApp extends StatelessWidget {
const MyApp({super.key});

@override
Widget build(BuildContext context) {
return const Placeholder();
}
}
Supprimer le code écrit après le return et le remplacer par le code de MaterialApp de
main.dart
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});

@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.red,
body: Container(),
),
);
}
}

Maintenant, lorsqu’on applique le Hot Reload, le changement sera pris en compte. De plus, il
n’est pas obligatoire de cliquer sur le Hot Reload à chaque fois, il suffit d’enregistrer le code,
les changements seront mis en considération.
Si on veut faire des changements sur les fonctionnalités, il faut utiliser le Hot Refresh.
Par exemple, on ouvre l’application par défaut créé par flutter et on incrémente le nombre. Par
la suite, on change la couleur de l’arrière-plan et on clique sur le Hot Reload.
 On remarque que la couleur de l’arrière-plan est changée mais la valeur incrémentée
reste inchangée.

14
Le Container Widget
Container widget est similaire au div html d’une page Web.
Aller au flutter docs, dans la partie des Layout, on remarque qu’il existe deux types de layout
widget :
- Single –child Layout Widget
- Multi-child Layout Widget
Le container sans enfants container() s’étale sur tout l’espace de l’écran du téléphone. Si on
veut ajouter dans ce container une couleur de fond blanche, il faut utiliser sa propriété ‘color’.
On écrit alors le code suivant :
body: Container(
color: Colors.white,
),

On remarque que l’arrière-plan du téléphone sera tout blanc même si nous avons déjà choisi la
couleur rouge comme couleur d’arrière-plan. Puisque le container n’a aucun enfant, il occupe
tout l’espace c’est pourquoi il a caché la couleur d’arrière-plan. Maintenant, on va ajouter un
enfant dans le container. Cette enfant est un Text Widget.
body: Container(
child: Text('hello world '
),
color: Colors.white,
),

15
Le container va prendre la taille du texte et il s’affiche au côté haut-gauche de l’écran.
Si on veut que les containers s’affichent sur le body du téléphone.
 La solution : on utilise SafeArea widget et le container sera l’enfant de SafeArea.
SafeArea : Un widget qui insère son enfant avec un remplissage suffisant pour éviter les
intrusions du système d'exploitation. Par exemple, cela indentera suffisamment l'enfant
pour éviter la barre d'état en haut de l'écran. Cela indentera également l'enfant de la
quantité nécessaire pour éviter l'encoche sur l'iPhone X ou d'autres caractéristiques
physiques créatives similaires de l'écran.
Lorsqu'un remplissage minimum est spécifié, le plus grand des remplissages minimums
ou de la zone de sécurité sera appliqué.
On clique sur le mot container, une lampe s’affiche à côté du mot. Lorsque on clique cette
lampe, les choix suivants s’affichent. On utilise « wrap with widget » et remplacer le mot
widget le mot SafeArea.

16
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.cyan[700],
body: SafeArea(
child: Container(
child: Text('hello world '
),
color: Colors.white,
),
),
),
);
}
}

Si on veut changer la longueur et la largeur du container, on peut utiliser les attributs width et
height comme le code suivant :
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.cyan[700],

17
body: SafeArea(
child: Container(
child: Text('hello world '
),
color: Colors.white,
width :200.0,
height :200.0,
),),),); }}

De plus, on peut appliquer des marges à extérieurs au container en utilisant la ligne suivante :
margin :EdgeInsets. (Plusieurs options)
- All (value) : applique une seule valeur sur les 4 cotés.
- fromTRB(value of left, value of top, value of right, value of bottom) : ajout des
différents valeurs tout en respectant l’ordre d’ajout.
- Only (left:value): dans ce type, il faut spécifie au vous voulez ajouter une marge.
- Symmetric(vertical :100.0,horizontal :10.0) : ajout en haut et en bas 100 pixels et ajout
au droite et au gauche 10.0 pixels.
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.cyan[700],
body: SafeArea(
child: Container(
child: Text('hello world '),
color: Colors.white,
width: 200.0,
height: 200.0,
margin: EdgeInsets.all(20.0),
),
),
),
);
}

18
}

De plus, on peut ajouter des marges intérieures au container en utilisant la ligne suivante :
padding : EdgeInsets. (Avec les mêmes options des marges).
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.cyan[700],
body: SafeArea(
child: Container(
child: Text('hello world '),
color: Colors.white,
width: 200.0,
height: 200.0,
margin: EdgeInsets.all(20.0),
padding: EdgeInsets.symmetric(vertical: 50.0, horizontal: 30.0),
),),), ); }}

19
Columns et Rows Widgets
On veut maintenant utiliser plusieurs containers. On utilise les columns et les rows.
Row et Column sont les deux widgets les plus importants et les plus puissants de Flutter. Ces
widgets vous permettent d'aligner les enfants horizontalement et verticalement selon les
besoins.
Par exemple, on veut créer 3 containers dans un column widget. Column widget est composé
par des enfants (children). Cet widget sera l’enfant du SafeArea widget et les containers widget
seront les children des column widget. Le code de création de ces derniers est le suivant :
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.cyan[700],
body: SafeArea(
child: Column(
children:[
Container(
child: Text('Container 1'
),
color: Colors.white,
width :200.0,
height :200.0,
),
Container(
child: Text('Container 2'
),
color: Colors.blue,
width :200.0,
height :200.0,
),
Container(
child: Text('Container 3'
),
color: Colors.red,
width :200.0,
height :200.0,
),
],),),),);}}

20
Remarque : Largeur du column widget est égal à la plus grande largeur d’un container
widget. On veut maintenant changer la largeur de la colonne, on utilise la propriété suivante
qui est « taille du l’axe principal » du Column widget :
mainAxisSize: MainAxisSize.max,
On utilise les propriétés (attributs) suivantes du Column widget pour afficher les containers :
- De bas en haut : verticalDirection: VerticalDirection.up,

21
- De haut en bas : verticalDirection: VerticalDirection.down, (par défaut)

De plus, si on veut voir des espaces entre les containers, on utilise la propriété « l’alignement
du l’axe principal » :
- De haut en bas : mainAxisAlignment: MainAxisAlignment.start, (par défaut)

22
- De bas en haut : mainAxisAlignment: MainAxisAlignment.end,

- Centrée : mainAxisAlignment: MainAxisAlignment.center,

23
- Calculer les espaces et repositionner les containers sur tous l’espace de l’écran :
mainAxisAlignment: MainAxisAlignment.SpaceEventy,

- Affiche container 1 en haut, container 2 au centre et container 3 en bas :


mainAxisAlignment: MainAxisAlignment.SpaceBetween

24
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.cyan[700],
body: SafeArea(
child: Column(
mainAxisSize: MainAxisSize.max,
//verticalDirection: VerticalDirection.up,
// mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
child: Text('Container 1'),
color: Colors.white,
width: 200.0,
height: 200.0,
),
Container(
child: Text('Container 2'),
color: Colors.blue,
width: 200.0,
height: 200.0,
),
Container(
child: Text('Container 3'),
color: Colors.red,
width: 200.0,
height: 200.0,
),],), ),), ); }}

Les propriétés décrites dans la partie précédente permettent de modifier les positions sur l’axe
verticales. Maintenant, pour changer les emplacements sur l’axe horizontal, on utilise les
propriétés suivantes :
crossAxisAlignment : CrossAxisAlignment.start (par défaut)
crossAxisAlignment : CrossAxisAlignment.end

Puisque la colonne a la taille des containers, et tous les containers ont la même largeur, alors
crossAxisAlignment : CrossAxisAlignment.start et crossAxisAlignment :
CrossAxisAlignment.end donnent la même chose. La première solution est de changer l’une
des largeurs des containers. Alors, on va remarquer la différence entre des deux lignes de
crossAxisAlignment.
- crossAxisAlignment : CrossAxisAlignment.start: affiche les containers à la côté
gauche de téléphone

25
- crossAxisAlignment : CrossAxisAlignment.end: affiche les containers à la coté droite
de téléphone

26
Ainsi, la deuxième solution est de déplacer les containers à la coté droite, on utilise un
container invisible avec une largeur infinie comme le code suivant :
child: Column(
//mainAxisSize: MainAxisSize.min,
//verticalDirection: VerticalDirection.down,
//mainAxisAlignment: MainAxisAlignment.spaceBetween,
//crossAxisAlignment: CrossAxisAlignment.end,
children: [
Container(
child: Text('Container 1'),
color: Colors.white,
width: 200.0,
height: 200.0,
),
Container(
child: Text('Container 2'),
color: Colors.blue,
width: 200.0,
height: 200.0,
),
Container(
child: Text('Container 3'),
color: Colors.red,
width: 200.0,

27
height: 200.0,
),
Container(
width: double.infinity,
),
],

Maintenant, si on veut que les containers s’affichent à toute la largeur de l’écran du téléphone,
on peut changer toutes les largeurs des containers à l’infini. Ou bien, on supprime la ligne de
width et on utilise la propriété crossAxisAlignment avec l’option stretch.
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Container(
child: Text('Container 1'),
color: Colors.white,
height: 200.0,
),
Container(
child: Text('Container 2'),
color: Colors.blue,
height: 200.0,
),

28
Container(
child: Text('Container 3'),
color: Colors.red,
height: 200.0,
),
],

De plus, pour voir des espaces (avec une taille fixée par le développeur d’application) entre
les containers, on utilise SizeBox widget qui a deux propriétés : height et width. Dans notre
cas, on va utiliser la propriété « height ».
children: [
Container(
child: Text('Container 1'),
color: Colors.white,
height: 200.0,
),
SizedBox(
height: 30.0,
),
Container(
child: Text('Container 2'),
color: Colors.blue,
height: 200.0,
),
SizedBox(
height: 30.0,
),
Container(
child: Text('Container 3'),
color: Colors.red,
height: 200.0,
),
],

29
Les fonctionnalités étaient appliquées au column widget, sont les mêmes pour les Rows
widget.
Réplacer le mot « column » dans notre code par le mot « row »et observer la différence entre
les deux widgets.
Circle Avatar
Le design de notre application commence de haut en bas  Alors, on va utiliser Column
widget. Dans le main.dart, on écrit le code suivant :
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
CircleAvatar(
radius: 50.0,
backgroundColor: Colors.white,
), ],),

30
Pour ajouter une Image à notre application, il faut :
1. Créer un dossier nommé « images » dans notre projet et qui contient l’image à utiliser.
2. Modifier le fichier de configuration paubspec.yaml par les lignes suivantes :
assets:
- images/
3. On remplace la couleur d’arrière-plan par une image en arrière-plan par la ligne
suivante
CircleAvatar(
radius: 50.0,
backgroundImage: AssetImage('images/figure1.jpg'),
),
Maintenant, nous allons ajouter les deux Text widget qui contiennent le nom et le prénom de
la personne (Text widget 1) et leur fonction (Text widget 2).

On remarque que le texte s’affiche en couleur noir et avec une petite taille. Pour les modifier,
dans la propriété « Style » du « Text widget », on utilise « TextStyle widget ».
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
CircleAvatar(
radius: 50.0,
backgroundImage: AssetImage('images/figure1.jpg'),
),
Text('Takoua Soltani'
style: TextStyle(
fontSize: 30.0,

31
color: Colors.white,
fontWeight: FontWeight.bold,
),),
],

Ajouter des fonts


On veut modifier la police du texte, il faut suivre les étapes suivantes :
1. Télécharger la police à partir de site de Google fonts : fonts.google.com. Toutes les
polices sont gratuites. Il existe plus de 900 polices. On peut choisir selon les filtres
existants dans le site.

2. Par exemple, on veut une police « Latin » du filtre « Langages », il affiche les polices
en Latin

32
3. On choisit l’un des styles, par exemple, « Cairo ». Pour ce Style, il existe plusieurs
écritures. On peut télécharger toute l’ensemble ou télécharger une seule. Par exemple
« Bold 700 ».

4. Télécharger cette police par cliquer sur « Download all ». Un fichier .zip va être
téléchargé. Le décompresser et vous trouverez les polices suivantes :

33
5. Créer un dossier nommé « Fonts » dans notre projet. Dans le dossier « Fonts », placer
l’un des polices décompressées par exemple « Cairo-ExtraBold »
6. Dans le fichier pubspec.yaml, on a un commentaire sur les fonts « #fonts », la
décommenté par supprimer les #.
7.

8. Changer la « famille » par « Cairo » et « assets » par Cairo-ExtraBold comme suit :

34
9. Enregistrer les modifications créées dans le fichier de configuration
10. Dans le code de fichier main.dart, on utilise dans le TextStyle la
propriété « fontFamily: 'Cairo', » (même famille écrit dans pubspec.yaml).
11. Exécuter le code suivant :
import 'dart:math';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}

class MyApp extends StatelessWidget {


const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.cyan[700],
body: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CircleAvatar(
radius: 50.0,
backgroundImage: AssetImage('images/figure1.jpg'),
),
Text(

35
'Takoua Soltani',
style: TextStyle(
fontFamily: 'Cairo',
fontSize: 30.0,
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
Text(
'Teacher',
style: TextStyle(
fontFamily: 'Cairo',
fontSize: 30.0,
color: Colors.white,
fontWeight: FontWeight.bold,
), ),],),),), ); }}
12. Si une erreur se produit, fermer l’émulateur puis réouvrir pour voir les modifications

Add Icons

Après les circleAvartar et les deux texts widgets, on va utiliser une Icon. L’utilisation sera
simple à modifié que les images (circle Avatar), ces derniers sont les enfants du column
widget. Maintenant, on va ajouter un container qui présente un nouvel enfant qui contient un
Icon widget de google et pour mieux choisir des couleurs cohérentes vous pouvez utiliser
materials.pallette.com (permet de choisir un couleur à votre application).

Icon Widget
On veut utiliser une icône de téléphone, alors le code correspondant est :
Icon(
Icons.phone,
color: Colors.red,
),

36
Container(
child: Row(
children: [
Icon(
Icons.phone,
color: Colors.red,
),
Text(
'N° tel 000000',
style: TextStyle(
fontSize: 30.0,
fontWeight: FontWeight.bold,
color: Colors.red,
),
),
],
),
),

child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
CircleAvatar(
radius: 50.0,
backgroundImage: AssetImage('images/figure1.jpg'),

37
),
Text(
'Takoua Soltani',
style: TextStyle(
fontFamily: 'Cairo',
fontSize: 30.0,
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
Text(
'Teacher',
style: TextStyle(
fontFamily: 'Cairo',
fontSize: 30.0,
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
Container(
child: Row(
children: [
Icon(
Icons.phone,
color: Colors.red,
),], ), ), ], ),

38
Pour ajouter un espace entre l’icône et le numéro de téléphone, on utilise SizeBox widget.
Alors, on écrit le code suivant :
children: [
Icon(
Icons.phone,
color: Colors.red,
),
SizedBox(
width: 20.0,
),
Text(
'N° tel 000000',
style: TextStyle(
fontSize: 30.0,
fontWeight: FontWeight.bold,
color: Colors.red,
),
),
],

Maintenant, on veut donner une couleur blanche, une marge à tous les côtés égale à 20 pixels
et un padding à tous les côtés égal à 10 pixels à notre container. On écrit :

Container(
color: Colors.white,
margin: EdgeInsets.all(20.0),

39
padding: EdgeInsets.all(10.0),
child: Row(
children: [
Icon(
Icons.phone,
color: Colors.red,
),
SizedBox(
width: 20.0,
),
Text(
'N° tel 000000',
style: TextStyle(
fontSize: 30.0,
fontWeight: FontWeight.bold,
color: Colors.red,
),
),
],
),
),

Après la préparation de container 1, on va créer un deuxième container qui contient


« l’email ». Alors, on écrit le code suivant :
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override

40
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.cyan[700],
body: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CircleAvatar(
radius: 50.0,
backgroundImage: AssetImage('images/figure1.jpg'),
),
Text(
'Takoua Soltani',
style: TextStyle(
fontFamily: 'Cairo',
fontSize: 30.0,
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
Text(
'Teacher',
style: TextStyle(
fontFamily: 'Cairo',
fontSize: 30.0,
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
Container(
color: Colors.white,
margin: EdgeInsets.all(20.0),
padding: EdgeInsets.all(10.0),
child: Row(
children: [
Icon(
Icons.phone,
color: Colors.cyan[700],
),
SizedBox(
width: 20.0,
),
Text(
'N° tel 000000',
style: TextStyle(
fontSize: 30.0,
fontWeight: FontWeight.bold,
color: Colors.cyan[700],

41
),
),
],
),
),
Container(
color: Colors.white,
margin: EdgeInsets.all(20.0),
padding: EdgeInsets.all(10.0),
child: Row(
children: [
Icon(
Icons.email,
color: Colors.cyan[700],
),
SizedBox(
width: 20.0,
),
Text(
'xxxx@gmail.com',
style: TextStyle(
fontSize: 30.0,
fontWeight: FontWeight.bold,
color: Colors.cyan[700],
), ),],
),
),
],
),
),
),
);
}
}

42
2ème solution : En utilisant Card, ListTile Widgets

But : est une présentation plus élégante : des côtés des containers circulaires et un arrière-plan
(shadow).
La solution est l’utilisation de card widget. Ce composant est créé par google qui remplace le
container widget. De plus, ce widget a la couleur blanche comme couleur d’arrière-plan.
Alors, on peut supprimer la ligne qui donne le couleur d’arrière-plan de notre code.
De plus, le card widget n’a pas une propriété nommée padding.
 Il faut supprimer la ligne de padding. Et pour ajouter des espaces dans le card widget,
on va utiliser un widget nommé padding
 Dans le container widget de la 1ére solution, on a utilisé des Row widget qui contient :
Icon widget, SizeBox widget et Text widget. Maintenant, pour voir des espaces dans
le card widget, il faut placer le Row widget comme enfant d’un padding widget. On
clique sur Row, après la lampe à coté et on choisi « wrap with padding ».

class MyApp extends StatelessWidget {


const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Colors.cyan[700],
body: SafeArea(
child: Column(

43
mainAxisAlignment: MainAxisAlignment.center,
children: [
CircleAvatar(
radius: 50.0,
backgroundImage:
AssetImage('images/figure1.jpg'),
),
Text(
'Takoua Soltani',
style: TextStyle(
fontFamily: 'Cairo',
fontSize: 30.0,
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
Text(
'Teacher',
style: TextStyle(
fontFamily: 'Cairo',
fontSize: 30.0,
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
Card(
margin: EdgeInsets.all(20.0),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Icon(
Icons.phone,
color: Colors.cyan[700],
),
SizedBox(
width: 20.0,
),
Text(
'N° tel 000000',
style: TextStyle(
fontSize: 30.0,
fontWeight: FontWeight.bold,
color: Colors.cyan[700],
),),],),),),
Card(
margin: EdgeInsets.all(20.0),
child: Padding(
padding: const EdgeInsets.all(8.0),

44
child: Row(
children: [
Icon(
Icons.email,
color: Colors.cyan[700],
),
SizedBox(
width: 20.0,
),
Text(
'xxxx@gmail.com',
style: TextStyle(
fontSize: 30.0,
fontWeight: FontWeight.bold,
color: Colors.cyan[700],
),),],),),),],),),),); }}

Le padding widget a comme valeur par défaut 8.0 pixels. On va changer cette valeur à 25.0
pixels. De plus, on peut utiliser un autre type de widget à la place de Row widget qui est l’un
des propriétés du card widget. Ce widget est ListTile.

Les composants leading et trailing peuvent contenir des icones ou des images. Et placer le
contenu de column widget au centre.
void main() {
runApp(MyApp());
}

class MyApp extends StatelessWidget {


const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(

45
home: Scaffold(
backgroundColor: Colors.cyan[700],
body: SafeArea(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
CircleAvatar(
radius: 50.0,
backgroundImage: AssetImage('images/figure1.jpg'),
),
Text(
'Takoua Soltani',
style: TextStyle(
fontFamily: 'Cairo',
fontSize: 30.0,
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
Text(
'Teacher',
style: TextStyle(
fontFamily: 'Cairo',
fontSize: 30.0,
color: Colors.white,
fontWeight: FontWeight.bold,
),
),
Card(
margin: EdgeInsets.all(20.0),
child: ListTile(
leading: Icon(
Icons.phone,
color: Colors.cyan[700],
),
title: Text(
'N° tel 000000',
style: TextStyle(
fontSize: 30.0,
fontWeight: FontWeight.bold,
color: Colors.cyan[700],
),
),
),
),
Card(
margin: EdgeInsets.all(20.0),
child: ListTile(
leading: Icon(

46
Icons.email,
color: Colors.cyan[700],
),
title: Text(
'xxxx@gmail.com',
style: TextStyle(
fontSize: 30.0,
fontWeight: FontWeight.bold,
color: Colors.cyan[700],
),),),),],),),),);}}

On veut maintenant ajouter une ligne qui sépare les deux parties Top et bottom de notre écran
de téléphone par une ligne. Alors, on utilise avant le code de card widget le code suivant :

SizedBox(
height: 20.0,
child: Divider(
color: Colors.cyan[100],
),
),
Ces lignes de codes permettent de créer un SizeBox widget avec longueur égal à 20.0 pixels et
divider widget qui permet d’avoir une ligne sur toute la largeur de l’écran de téléphone. Si on
veut manipuler la largeur de ligne créé par le Diviser, on utilise propriété width dans le
SizeBox widget. On peut donner à cette variable width la valeur 200.0 pixels.

Changer Icône de notre application


L’icône par défaut de notre application créé prend l’icône du flutter. Pour la changer, on va
suivre les étapes suivantes :
1. Créer notre propre icône par exemple par photoshop.
2. Accéder au site « appicon.co ».

47
3. Copier votre image d’icône et choisir le système pour laquelle on veut voir cette
icône. Dans notre cas, on veut que l’icône s’applique aux deux systèmes Android et
iOS.

4. Cliquer sur « Generate ». Un fichier .zip va être créé


5. Décompresser le fichier.zip. Dans ce dernier, il existe deux dossiers : l’un pour
l’Android et l’autre pour Apple.
6. Retourner maintenant au Visual Studio code. Aller au dossier nommé « Android »,
ainsi dans le dossier nommé « app », par la suite, aller dans le dossier « src ». Dans ce
dernier, choisir le dossier « main » ainsi le dossier « res ».

48
Cliquer sur le bouton droit et choisir « Reveal in file explorer ou afficher dans l’explorateur
de fichiers ». Ouvrir le dossier « res » et supprimer les 5 dossiers placer dans le cadre de la
figure précédente et les remplacer par celle du fichier .zip (générer par le site appicon).

49
Passant maintenant au dossier « ios ». Ainsi, dans ce dernier, choisir le dossier « Runner ».
Par la suite, déplacer dans le dossier « Assets.Xcassets ». Cliquer sur le bouton droit à cote de
ce dernier dossier et choisir « Afficher dans l’explorateur de fichiers ».
Supprimer le dossier « Assets.Xcassets » de notre application et le remplacer par celle créé
par site appicon.co.

Démarrer par la suite l’émulateur. Notre application s’affiche. On clique sur le bouton
principal. On remarque que l’icône de notre application a l’icône souhaité.

50
Voir notre application sur un téléphone réel, non pas sur l’émulateur

1. Appliquer le « mode développeur »


1.1.Aller au paramètre de téléphone
1.2.Choisir « Info sur téléphone »
1.3.Dans cette partie, il faut voir le numéro de version de notre téléphone
1.4.Cliquer sur la version entre 3 à 7 fois
1.5.Retourner au paramètre, on remarque que le mode développeur est visible
1.6.Entrer dans cette partie et activer, corriger erreurs USB (USB debugging)
2. Connecter le téléphone au PC par un câble USB. Remarque : Il est préféré que le
câble utilisé soit d’origine pour assurer la connexion.
3. Aller au Visual Studio Code, choisir votre téléphone à la place de l’émulateur.
4. Exécuter le code du projet
 L’application s’affiche dans votre téléphone.

51

Vous aimerez peut-être aussi