Flutter : L’Art de la Navigation

Par bmarcelin, 15 mars, 2025
Barre inférieure avec feuille

📝 Introduction : Pourquoi la Navigation est-elle Essentielle ?

Dans une application Flutter, l’utilisateur doit pouvoir naviguer naturellement entre plusieurs écrans. Une application moderne n’est pas statique : elle doit guider l’utilisateur d’un point A à un point B avec fluidité, que ce soit via des boutons, un menu latéral, ou une barre d’onglets en bas de l’écran.

Flutter offre plusieurs outils puissants pour gérer cette navigation :
Le Navigator pour passer d’un écran à un autre.
Le BottomNavigationBar pour une navigation rapide entre plusieurs sections.
Le Drawer pour un menu latéral déployable.
Les routes nommées pour organiser une navigation structurée.

Dans cet article, nous allons explorer chacune de ces solutions, en expliquant quand et pourquoi les utiliser, avec des exemples concrets.

| source: https://www.mobiapps.fr/blog/flutter-la-navigation


1️⃣ Le Navigator : La Base de la Navigation

Flutter utilise un système de pile (stack) pour gérer les écrans. Chaque nouvel écran est empilé au-dessus des précédents, et lorsqu’un utilisateur appuie sur "Retour", l’écran est dépilé.

👉 Cas d’usage : Lorsque vous avez un bouton permettant de passer d’un écran à un autre.

** Exemple : Passer à une nouvelle page avec Navigator.push()**

Créons deux fichiers :

  • main.dart (page principale).
  • page2.dart (seconde page).

main.dart :

import 'package:flutter/material.dart';
import 'page2.dart'; // Importation de la deuxième page

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: const Page1(),
    );
  }
}

class Page1 extends StatelessWidget {
  const Page1({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Article : Flutter')),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.push(
              context,
              MaterialPageRoute(builder: (context) => const Page2()),
            );
          },
          child: const Text('Prendre le bus vers Rosemont'),
        ),
      ),
    );
  }
}

page2.dart :

import 'package:flutter/material.dart';

class Page2 extends StatelessWidget {
  const Page2({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Arrivé à Rosemont')),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.pop(context); // Revenir à la page précédente
          },
          child: const Text('Retour à la maison'),
        ),
      ),
    );
  }
}

Explication :

  • Navigator.push() ajoute un nouvel écran à la pile.
  • Navigator.pop() retire l’écran courant et revient en arrière.

Résultat : Navigation


2️⃣ Le BottomNavigationBar : Une Barre de Navigation Moderne

Un BottomNavigationBar est souvent utilisé pour permettre un accès rapide aux sections principales d’une application. C’est l’un des modèles de navigation les plus courants.

👉 Cas d’usage : Application avec 3 à 5 pages principales.

Exemple : Ajouter un BottomNavigationBar

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: const PageNavigation(),
    );
  }
}

class PageNavigation extends StatefulWidget {
  const PageNavigation({Key? key}) : super(key: key);

  @override
  _PageNavigationState createState() => _PageNavigationState();
}

class _PageNavigationState extends State<PageNavigation> {
  int _selectedIndex = 0;

  static const List<Widget> _pages = <Widget>[
    Center(child: Text('🏠 Le Collège de Rosemont', style: TextStyle(fontSize: 24))),
    Center(child: Text('👤 Je suis un étudiant', style: TextStyle(fontSize: 24))),
    Center(child: Text('⚙️ Apprendre la programmation', style: TextStyle(fontSize: 24))),
  ];

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Navigation avec BottomNavigationBar')),
      body: _pages[_selectedIndex], // Affiche la page sélectionnée
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: _selectedIndex,
        onTap: _onItemTapped,
        items: const [
          BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Rosemont'),
          BottomNavigationBarItem(icon: Icon(Icons.person), label: 'Étudiant'),
          BottomNavigationBarItem(icon: Icon(Icons.settings), label: 'Programmation'),
        ],
      ),
    );
  }
}

Explication :

  • _selectedIndex garde l’index actif.
  • _pages contient les trois écrans possibles.
  • setState() met à jour l’index lorsqu’un onglet est cliqué.

Résultat : BottomNavigation

| source: https://codewithandrea.com/articles/multiple-navigators-bottom-navigation-bar/

3️⃣ Drawer : Un Menu Latéral Déroulant

Un Drawer est utilisé pour accéder aux paramètres avancés ou aux pages moins courantes.

👉 Cas d’usage : Lorsque vous avez beaucoup d’options de navigation.

Exemple : Ajouter un Drawer avec plusieurs options :

Dans cet exemple, le Drawer (menu latéral) est intégré directement dans la page principale pour simplifier la démonstration.

💡 Cependant, dans une vraie application Flutter bien structurée, il est préférable de créer le menu sous forme de widget séparé et de l’importer dans la page principale.

Dans nos précédents articles, nous avons déjà vu comment créer un widget dédié et l’importer. Pour rappel, voici les étapes générales :

1️⃣ Créer un fichier séparé mon_drawer.dart et y définir le Drawer.
2️⃣ L’importer dans main.dart et l’utiliser dans le Scaffold.
3️⃣ Maintenir un code propre et modulaire pour une meilleure organisation.

👉 Comme cet article est déjà long, nous avons réalisé l’exemple avec le menu directement dans la page.
👉 Pour une mise en œuvre plus professionnelle, merci de vous référer à nos précédents articles sur la création et l'importation des widgets.

Pourquoi utiliser un fichier séparé pour le Drawer ?
Meilleure organisation : Séparer la logique de navigation du reste du code.
Réutilisation facile : Le menu peut être utilisé dans plusieurs pages.
Facilitation de maintenance : Modifier le menu sans toucher à la page principale.

import 'package:flutter/material.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: const PagePrincipale(),
    );
  }
}

class PagePrincipale extends StatefulWidget {
  const PagePrincipale({Key? key}) : super(key: key);

  @override
  _PagePrincipaleState createState() => _PagePrincipaleState();
}

class _PagePrincipaleState extends State<PagePrincipale> {
  int _selectedIndex = 0;

  static const List<Widget> _pages = <Widget>[
    Center(child: Text('🏠 Le Collège de Rosemont', style: TextStyle(fontSize: 24))),
    Center(child: Text('👤 Je suis un étudiant', style: TextStyle(fontSize: 24))),
    Center(child: Text('⚙️ Programmation', style: TextStyle(fontSize: 24))),
  ];

  void _onItemTapped(int index) {
    setState(() {
      _selectedIndex = index;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Application Flutter')),
      drawer: Drawer(
        child: ListView(
          padding: EdgeInsets.zero,
          children: [
            const DrawerHeader(
              decoration: BoxDecoration(color: Colors.blue),
              child: Text('Menu de Navigation',
                  style: TextStyle(color: Colors.white, fontSize: 20)),
            ),
            ListTile(
              leading: const Icon(Icons.info),
              title: const Text('Étudiant'),
              onTap: () {
                ScaffoldMessenger.of(context).showSnackBar(
                    const SnackBar(content: Text('À propos sélectionné')));
              },
            ),
            ListTile(
              leading: const Icon(Icons.help),
              title: const Text('Rosemont'),
              onTap: () {
                ScaffoldMessenger.of(context).showSnackBar(
                    const SnackBar(content: Text('Support sélectionné')));
              },
            ),
            ListTile(
              leading: const Icon(Icons.logout),
              title: const Text('Déconnexion'),
              onTap: () {
                Navigator.pop(context);
              },
            ),
          ],
        ),
      ),
      body: _pages[_selectedIndex],
      bottomNavigationBar: BottomNavigationBar(
        currentIndex: _selectedIndex,
        onTap: _onItemTapped,
        items: const [
          BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Rosemont'),
          BottomNavigationBarItem(icon: Icon(Icons.person), label: 'Étudiant'),
          BottomNavigationBarItem(icon: Icon(Icons.settings), label: 'Programmation'),
        ],
      ),
    );
  }
}


Explication :

  • DrawerHeader affiche le titre du menu.
  • ListTile représente chaque option du menu.

MenuLatteral

| source: https://docs.flutter.dev/cookbook/navigation/navigation-basics

Conclusion

Nous avons exploré les méthodes essentielles de navigation en Flutter. Chaque approche a son usage optimal selon la structure de l’application.

👉 Dans le prochain article, nous verrons les animations et transitions avancées en Flutter !

Références :

Site officiel de Flutter : https://flutter.dev/ (Page consultée le 14 mars 2025).
Documentation Flutter : https://docs.flutter.dev/ (Page consultée le 14 mars 2025).
FAQ Flutter : https://docs.flutter.dev/resources/faq (Page consultée le 14 mars2025).
Flutter (logiciel) – Wikipédia : https://fr.wikipedia.org/wiki/Flutter_(logiciel) (Page consultée le 14 mars 2025).
Flutter sur GitHub (open source) : https://github.com/flutter/flutter (Page consultée le 14 mars 2025).
Code with Andrea (Tutoriel) : https://codewithandrea.com/articles/multiple-navigators-bottom-navigation-bar/ (Page consultée le 14 mars 2025).
Site officiel de Flutter : https://docs.flutter.dev/cookbook/navigation/navigation-basics (Page consultée le 14 mars 2025).
Lien pour la première image et aussi pour un tuto sur la navigation : https://www.kindacode.com/article/flutter-best-packages-to-create-bottom-app-bar (Page consultée le 14 mars 2025).


À très bientôt !

Commentaires1

nbrahimi

il y a 1 semaine

C'est très intéressant de voir l'animation de Flutter en temps réel, tu nous présente de très bons exemples concrets ! Je me demandais quel widget de navigation t'as paru le plus adapté pour tes exemples ? (Drawer, BottomNavigationBar, ou Navigator)