Widgets pour construire sa page
Comme pour un site web, une application mobile se présentent sous la forme de “page” à travers lesquels l’utilisateur va pouvoir naviguer. La première chose à faire est donc de construire un widget de type MaterialApp(), qui va contenir un Scaffold() (échafaudage), qui va nous servir de squelette. C’est ensuite dans ce Scaffold que l’on va venir placer le body() (corps) de notre app, ainsi qu’une éventuelle AppBar() ou une BottomAppBar().
Scaffold
Le Scaffold est le widget que vous allez venir placer dans le paramètre home de votre MaterialApp(). Si la MaterialApp() sert de toile blanche, le Scaffold est plutôt le squelette de votre app, qui va permettre de construire vos éléments visuels. Celui-ci se compose de 3 paramètres optionnels, néanmoins importants, que sont :
- appBar, qui prend comme argument un widget de type AppBar() ;
- body, qui peut prendre comme argument un Container, Center(), une colonne, etc ;
- bottomNavigationBar, qui prend comme argument un widget de type BottomAppBar().
C’est avec ces trois éléments que vous allez pouvoir commencer à construire le visuel de votre application.
Vous pouvez utiliser ce code pour commencer à vous entrainer et à comprendre comment les widgets se “nichent” les uns dans les autres :
void main() => runApp(const MonExempleDeScaffold());
class MonExempleDeScaffold extends StatelessWidget {
const MonExempleDeScaffold({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: ExempleScaffold(),
);
}
}
class ExempleScaffold extends StatefulWidget {
const ExempleScaffold({super.key});
@override
State<ExempleScaffold> createState() => _ExempleScaffoldState();
}
class _ExempleScaffoldState extends State<ExempleScaffold> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundcolor: Colors.blueGrey.shade200,
title: const Text('AppBar d’exemple'),
),
body: Center(child: Text('Le corps de mon application se trouve ici”')),
backgroundColor: Colors.white,
);
}
}
Ici, ma fonction runApp(), lance ma MaterialApp(), sur laquelle repose mon Scaffold() qui contient tous les éléments visuels de ma page.
AppBar
La AppBar() désigne une bande en haut de l’écran dans laquelle vous allez pouvoir insérer d’autres widgets, comme du texte, des icônes ou bien des boutons. Par exemple, vous pouvez l’utiliser pour créer un menu en haut de votre page, ou insérer un espace pour que le contenu de votre application ne soit pas masqué par la caméra du téléphone.
BottomAppBar
La BottomAppBar() fonctionne de la même manière que la AppBar, à la différence que celle-ci va se trouver en bas de votre téléphone. Une utilisation classique de celui-ci est de créer un menu d’icônes, permettant de naviguer à travers les sections de votre téléphone. Par exemple, voici un menu que j’ai pu créer en utilisant ce widget dans lequel je suis venu placer une TabBar().
Je vous partage le code, que vous pouvez réutiliser et personnaliser selon vos besoins :
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
@override
Widget build(BuildContext context) {
return Scaffold(
extendBody: true,
backgroundColor: Colors.white,
bottomNavigationBar: BottomAppBar(
color: Colors.transparent,
elevation: 0,
child: menu(),
),
body: const TabBarView(
children: [
Page1(),
Page2(),
/*
C’est ici que vous devez placer vos différentes pages, dont le nombre doit être égal à celui des Tabs. Ajoutez ou retirez des Tabs selon vos besoins. */
],
));
}
Widget menu() {
return Container(
margin: EdgeInsets.only(right: 25, left: 25),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(40),
border: Border.all(
width: 0.05,
color: Color.fromARGB(255, 24, 83, 79),
),
color: Colors.white.withOpacity(0.9),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.2),
spreadRadius: 2,
blurRadius: 5,
offset: Offset(0, 5),
),
]),
child: TabBar(
labelPadding: EdgeInsets.all(5),
labelColor: Color.fromARGB(255, 33, 46, 83),
dividerColor: Colors.transparent,
unselectedLabelColor: Color.fromARGB(255, 33, 46, 83).withOpacity(0.4),
indicatorSize: TabBarIndicatorSize.label,
indicatorPadding: EdgeInsets.only(bottom: 5.0),
indicatorColor: Color.fromARGB(255, 206, 106, 107),
tabs: const [
Tab(
icon: Icon(
Ionicons.home,
size: 27,
),
),
Tab(
icon: Icon(
Ionicons.school,
size: 27,
),
),
],
),
);
}
}
Widgets lignes et colonnes
Une fois votre page créée, vous allez pouvoir y ajouter vos boutons, vos images, zones de textes, etc. J’imagine cependant que vous allez vouloir les positionner à un endroit exact de votre application et pas juste de manière aléatoire. C’est à ce moment que les widgets Row() (ligne) et Column (colonne), vont vous aider.
Ces deux widgets vont, comme leurs noms l’indiquent, vous permettre d’empiler plusieurs widgets soit dans le sens de la hauteur, soit dans celui de la largeur. Ils sont d’autant plus importants à maitriser qu’un simple Container(), ne peut prendre qu’un seul widget dans son paramètre Child. Cela veut donc dire que je ne pourrai, par exemple, placer qu’un seul texte dans celui-ci. Les widgets Row et Column règlent ce problème en vous permettant d’intégrer autant de widgets que vous le souhaitez dans son paramètre children.
Voici un exemple simple de l’usage des widgets Row et Column :
class ExampleRowColumn extends StatefulWidget {
const ExampleRowColumn({super.key});
@override
State<ExampleRowColumn> createState() => _ExampleRowColumnState();
}
class _ExampleRowColumnState extends State<ExampleRowColumn> {
@override
Widget build(BuildContext context) {
return SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
color: Colors.purple,
height: MediaQuery.of(context).size.height * 0.08,
width: MediaQuery.of(context).size.width * 0.3,
child: TextButton(
onPressed: () {
},
child: Text(
"Connexion",
style: TextStyle(color: Colors.white),
))),
Container(
color: Colors.red,
height: MediaQuery.of(context).size.height * 0.08,
width: MediaQuery.of(context).size.width * 0.3,
child: TextButton(
onPressed: () {
},
child: Text(
"Déconnexion",
style: TextStyle(color: Colors.white),
))),
],
),
);
}
}
Widgets pour ajouter du contenu
Vous avez construit votre page et savez organiser du contenu sur celle-ci ? Il est maintenant temps d’ajouter vos différents éléments visuels.
Container
Le widget Container(), vous permet de créer une zone de type rectangulaire. Vous allez pouvoir lui donner une hauteur, une largeur, une couleur, des marges, un bord, etc. Mais le plus important est que vous allez ensuite pouvoir placer un widget enfant dans celui-ci, qui va remplir l’espace. Le Container est donc un bon moyen de délimiter un espace dans lequel vous allez placer un élément visuel de votre application, comme une zone de texte, une image, un bouton, etc.
Text
Le Widget Text(), comme son nom l’indique, vous permet d’ajouter des éléments textuels à votre application. Ce widget vient avec différents paramètres vous permettant de définir le style de votre texte, comme sa couleur, sa taille, son épaisseur, etc.
Image
Ajouter des images est aussi quelque chose d’important lorsqu’on créer une application, par exemple pour une page de profil. Flutter permet donc facilement d’intégrer des éléments visuels, avec son widget Image(), suivi d’une des deux méthodes suivantes :
- .asset() -> Permet d’intégrer des images ou des GIFs conservées dans vos dossiers d’applications et ajoutées à votre dossier pubspec.yaml ;
- .network() -> Permet d’intégrer des images ou des GIFs accessibles en ligne, via leur url.
Icon
Comme les images, les icones sont des éléments visuels important pour construire une application, notamment pour créer des boutons. Le widget Icon() vous permet ainsi d’intégrer un icone à votre application et de modifier son style, notamment sa couleur, sa taille, etc.
Il existe de nombreux packages vous permettant d’accéder à des ressources d’icones gratuits en ligne. Pour en savoir plus, je vous invite à lire mon guide sur les packages d’icones Flutter.
ElevattedButton
Pour permettre à vos utilisateurs d’interagir avec votre application, vous aurez besoin de lui ajouter des boutons. Et la manière la plus simple de le faire est d’utiliser le widget ElevattedButton. Celui-ci vous permet de créer à peu près n’importe quel type de button, que ce soit à partir d’une forme, d’un texte ou bien d’un icone et de lui intégrer une fonction. Par exemple :
Container(
height: MediaQuery.of(context).size.height * 0.06,
width: MediaQuery.of(context).size.width * 0.5,
child: ElevatedButton(
onPressed: () {
print(“Mon bouton fonctionne”);
},
style: ElevatedButton.styleFrom(
surfaceTintColor: Colors.white,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(30))),
side: const BorderSide(
color: Colors.black, width: 1)),
child: const Text("Bouton de test",
style: TextStyle(color: Colors.black))))
Conclusion
Ces widgets sont à la base de toute application et sont un bon point de d »part pour construire la vôtre. Apprenez à les utiliser en jouant avec leurs différentes propriétés, et tentez de reproduire les visuels d’autres applications. Si vous souhaitez en apprendre plus, j’ai rédigé un guide pour chacun d’entre deux :
- Guide complet Flutter : le widget Scaffold ;
- Guide complet Flutter : le widget Container ;
- Guide complet Flutter : le widget Column ;
- Guide complet Flutter : le widget Row ;
- Guide complet Flutter : le widget Text ;
- Guide complet Flutter : le widget Icon ;
- Guide complet Flutter : le widget Image ;
- Guide complet Flutter : le widget ElevattedButton ;
Une fois que vous maîtriserez la création de l’interface de votre application, il sera temps de vous pencher sur l’arrière-plan. Comment allez-vous stocker des données et les transmettre à vos utilisateurs ? Comment allez-vous gérer les comptes utilisateurs et les authentifier ? Je vous donne la réponse dans le prochain article :