Atelier Flutter
Atelier Flutter
Atelier Flutter
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.
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é.
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
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 ?
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 '
),
),
),
) ;
}
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
),
) ;
}
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
12
void main() {
runApp(MaterialApp(
home: Scaffold(
backgroundColor: Colors.cyan[700],
body: Container(),
),
));
}
@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,
23
- Calculer les espaces et repositionner les containers sur tous l’espace de l’écran :
mainAxisAlignment: MainAxisAlignment.SpaceEventy,
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,
),),
],
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.
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());
}
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,
),
),
],
),
),
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(
'[email protected]',
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 ».
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(
'[email protected]',
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());
}
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(
'[email protected]',
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.
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.
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
51