Aller au contenu principal

Le site sera en maintenance le 01/03/2026

Aller au contenu principal

Widgets Flutter essentiels : le guide complet des composants UI

Ce guide exhaustif t’apprend les widgets essentiels de Flutter : comprendre Stateless et Stateful, construire des interfaces avec Text, Image, Container, Row, Column et Stack, gérer listes et grilles ... et appliquer les bonnes pratiques pour créer des interfaces UI modernes.

M
Mpia
24/01/2026 22 min
244 vues
2 comme.
#Flutter#Widgets#UI
Widgets Flutter essentiels : le guide complet des composants UI

Salut ! Si tu développes avec Flutter, tu l'as probablement déjà entendu : "Everything is a widget" (tout est un widget). C'est pas juste un slogan marketing - c'est vraiment le cœur de Flutter. Chaque élément de ton interface, du plus simple bouton à l'écran complet, est un widget.

Le truc, c'est que Flutter propose des CENTAINES de widgets. Au début, ça peut être écrasant. Quel widget utiliser ? Quand utiliser Container vs SizedBox ? Text vs RichText ? Row vs ListView ?

Dans cet article, je vais te faire un tour complet des widgets essentiels de Flutter. On va explorer les widgets de base, les widgets de layout, les widgets d'interaction, et les widgets avancés. À la fin, tu sauras exactement quel widget utiliser dans chaque situation.

Prêt à devenir un maître des widgets ? Let's go ! 🚀

Comprendre les widgets Flutter

Avant de plonger tête baissée dans les widgets spécifiques, il faut vraiment comprendre ce qu'est un widget et comment Flutter fonctionne sous le capot.

Qu'est-ce qu'un widget ?

Un widget est une description de ce à quoi devrait ressembler une partie de ton interface. C'est important : un widget n'est PAS l'interface elle-même, c'est une configuration qui dit à Flutter comment construire l'interface.

Pense à un widget comme à un plan de construction. Tu donnes le plan (le widget) à Flutter, et Flutter construit la structure réelle (ce qu'on appelle les "elements" et "render objects").

Les widgets sont immuables - ils ne changent pas. Quand tu veux modifier quelque chose, Flutter crée un nouveau widget et reconstruit la partie concernée de l'interface. C'est ce qui rend Flutter si rapide : au lieu de modifier des objets complexes, on crée de nouveaux widgets légers.

Les deux types de widgets fondamentaux

Je te présente les deux catégories principales de widgets basées sur la gestion de l'état - c'est crucial pour bien coder en Flutter.

StatelessWidget : Les widgets sans état

Un StatelessWidget est complètement immuable. Une fois créé avec ses paramètres, il ne change jamais. Si tu veux modifier quelque chose, tu dois créer un nouveau widget entier.

Quand l'utiliser ? Pour les parties d'interface qui ne changent pas basées sur des interactions ou des données dynamiques.

Exemples d'usage :

  • Un logo statique

  • Un titre de section

  • Une carte de profil affichant des données fixes

  • Un icône

  • Un texte de copyright

class MonTitre extends StatelessWidget {
  final String texte;

  const MonTitre(this.texte);

  @override
  Widget build(BuildContext context) {
    return Text(
      texte,
      style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
    );
  }
}

// Utilisation
MonTitre('Bienvenue')

StatefulWidget : Les widgets avec état

Un StatefulWidget possède un état mutable qui peut changer durant le cycle de vie du widget. Quand l'état change via setState(), Flutter reconstruit automatiquement le widget.

Quand l'utiliser ? Pour les interfaces interactives ou dynamiques.

Exemples d'usage :

  • Formulaires avec validation

  • Compteurs et timers

  • Animations

  • Données qui changent (live updates)

  • Interfaces répondant aux interactions utilisateur

class Compteur extends StatefulWidget {
  @override
  _CompteurState createState() => _CompteurState();
}

class _CompteurState extends State<Compteur> {
  int _valeur = 0;

  void _incrementer() {
    setState(() {
      _valeur++; // Modifie l'état et déclenche rebuild
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Text('Compteur: $_valeur'),
        ElevatedButton(
          onPressed: _incrementer,
          child: Text('Incrémenter'),
        ),
      ],
    );
  }
}

La différence clé : StatelessWidget se reconstruit uniquement quand son parent change, StatefulWidget peut se reconstruire lui-même via setState().

Widgets de base : les fondations

Je te montre les widgets les plus simples - ceux que tu vas utiliser dans presque tous tes projets Flutter, tu veras.

Text : Afficher du texte

Le widget Text est probablement le plus utilisé. Il affiche du texte avec ou sans style.

Pourquoi l'utiliser ? Pour afficher n'importe quel contenu textuel : titres, paragraphes, labels, etc.

// Texte simple
Text('Bonjour Flutter!')

// Texte stylisé
Text(
  'Texte avec style',
  style: TextStyle(
    fontSize: 24,
    fontWeight: FontWeight.bold,
    color: Colors.blue,
    fontStyle: FontStyle.italic,
    decoration: TextDecoration.underline,
  ),
)

// Texte avec gestion du débordement
Text(
  'Un texte très long qui pourrait dépasser',
  maxLines: 2,
  overflow: TextOverflow.ellipsis, // Ajoute ... si trop long
)

Image : Afficher des images

Le widget Image permet d'afficher des images de différentes sources.

Pourquoi l'utiliser ? Photos, icônes personnalisées, logos, illustrations.

// Image depuis Internet
Image.network(
  'https://example.com/image.jpg',
  width: 200,
  height: 200,
  fit: BoxFit.cover,
)

// Image depuis les assets locaux
Image.asset(
  'assets/images/logo.png',
  width: 100,
)

// Gestion du chargement et erreurs
Image.network(
  url,
  loadingBuilder: (context, child, progress) {
    if (progress == null) return child;
    return CircularProgressIndicator();
  },
  errorBuilder: (context, error, stackTrace) {
    return Icon(Icons.error);
  },
)

Les options fit contrôlent comment l'image s'adapte :

  • BoxFit.cover : Remplit l'espace en gardant les proportions (crop possible)

  • BoxFit.contain : Image entière visible (peut laisser des espaces vides)

  • BoxFit.fill : Étire pour remplir (déforme l'image)

Icon : Afficher des icônes

Flutter inclut Material Icons (1000+ icônes) gratuitement.

Pourquoi l'utiliser ? Navigation, actions, indicateurs visuels.

Icon(Icons.home)

Icon(
  Icons.favorite,
  color: Colors.red,
  size: 48,
)

Widgets de layout : organiser l'interface

Les widgets de layout sont vraiment cruciaux - ils déterminent comment tous tes autres widgets sont positionnés et dimensionnés. C'est eux qui font la vraie structure.

Container : La boîte à tout faire

Container est le couteau suisse de Flutter. Il combine padding, margin, bordures, couleurs de fond et contraintes de taille.

Quand l'utiliser ? Quand tu as besoin de style, espacement, ou dimensions avec décoration.

Quand NE PAS l'utiliser ? Si tu as juste besoin d'espacement (utilise SizedBox/Padding pour de meilleures perfs).

Container(
  width: 200,
  height: 100,
  padding: EdgeInsets.all(16),
  margin: EdgeInsets.all(8),
  decoration: BoxDecoration(
    color: Colors.blue,
    borderRadius: BorderRadius.circular(12),
    boxShadow: [
      BoxShadow(
        color: Colors.black26,
        blurRadius: 8,
        offset: Offset(0, 4),
      ),
    ],
  ),
  child: Text('Contenu'),
)

Row et Column : Dispositions linéaires

Row dispose les widgets horizontalement, Column verticalement. Ce sont les bases de presque tous les layouts.

Quand utiliser Row ? Navigation bars, boutons côte à côte, informations en ligne.

Quand utiliser Column ? Formulaires, listes d'éléments verticaux, écrans avec sections empilées.

// Row - disposition horizontale
Row(
  mainAxisAlignment: MainAxisAlignment.spaceEvenly,
  children: [
    Icon(Icons.home),
    Icon(Icons.search),
    Icon(Icons.person),
  ],
)

// Column - disposition verticale
Column(
  crossAxisAlignment: CrossAxisAlignment.start,
  children: [
    Text('Titre'),
    SizedBox(height: 8),
    Text('Sous-titre'),
  ],
)

Les options d'alignement :

  • mainAxisAlignment : Aligne le long de l'axe principal (horizontal pour Row, vertical pour Column)

  • crossAxisAlignment : Aligne perpendiculairement

  • spaceEvenly : Espace égal partout

  • spaceBetween : Espace entre les éléments seulement

  • start/center/end : Position des éléments

Stack : Superposer des widgets

Stack permet de superposer des widgets les uns sur les autres, comme des calques Photoshop.

Quand l'utiliser ? Badges sur icônes, texte sur images, overlays, boutons flottants sur contenu.

Stack(
  children: [
    Image.network(url, fit: BoxFit.cover),
    Positioned(
      bottom: 16,
      left: 16,
      child: Text(
        'Légende',
        style: TextStyle(color: Colors.white),
      ),
    ),
  ],
)

Positioned te donne un contrôle précis de la position avec top, bottom, left, right.

Expanded et Flexible : Gérer l'espace

Ces widgets permettent aux enfants de Row/Column d'utiliser l'espace disponible intelligemment.

Expanded : Prend TOUT l'espace disponible. Flexible : Prend l'espace nécessaire mais peut être contraint.

Row(
  children: [
    Icon(Icons.star),
    Expanded(
      child: Text('Ce texte prend tout l espace disponible'),
    ),
    Icon(Icons.more_vert),
  ],
)

// Avec flex pour proportions
Row(
  children: [
    Expanded(
      flex: 2, // Prend 2/3
      child: Container(color: Colors.red, height: 50),
    ),
    Expanded(
      flex: 1, // Prend 1/3
      child: Container(color: Colors.blue, height: 50),
    ),
  ],
)

Widgets de défilement : gérer le contenu qui dépasse

Je te présente les widgets pour quand ton contenu devient trop gros - c'est là que le défilement entre en jeu.

ListView : Liste défilante

ListView est LE widget pour afficher des listes d'éléments.

Quand l'utiliser ? Listes de contacts, messages, produits, articles - tout contenu répétitif vertical.

Pourquoi ListView.builder ? Plus performant pour grandes listes car il ne crée que les éléments visibles.

// Liste avec enfants définis
ListView(
  children: [
    ListTile(title: Text('Item 1')),
    ListTile(title: Text('Item 2')),
  ],
)

// Builder pour grandes listes (RECOMMANDÉ)
ListView.builder(
  itemCount: 1000,
  itemBuilder: (context, index) {
    return ListTile(
      title: Text('Item numéro index'),
    );
  },
)

GridView : Grille défilante

GridView affiche des éléments en grille, parfait pour les galeries photos ou catalogues produits.

Quand l'utiliser ? Photos, produits, catégories, tout contenu qui bénéficie d'une présentation en grille.

GridView.count(
  crossAxisCount: 2, // 2 colonnes
  children: List.generate(20, (index) {
    return Card(
      child: Center(child: Text('Item index')),
    );
  }),
)

Widgets interactifs : répondre aux actions

Ces widgets permettent vraiment aux utilisateurs d'interagir avec ton app - c'est là que ça devient fun.

Boutons : Actions primaires

Flutter propose plusieurs types de boutons selon le design voulu.

ElevatedButton : Bouton élevé, action principale TextButton : Bouton texte, action secondaire OutlinedButton : Bouton avec bordure, action alternative

ElevatedButton(
  onPressed: () {
    print('Action principale');
  },
  child: Text('Valider'),
)

TextButton(
  onPressed: () {},
  child: Text('Annuler'),
)

Le paramètre onPressed: null désactive le bouton.

TextField : Saisie de texte

TextField permet à l'utilisateur d'entrer du texte.

Quand l'utiliser ? Formulaires, recherche, commentaires, tout input utilisateur.

TextField(
  decoration: InputDecoration(
    labelText: 'Nom',
    hintText: 'Entrez votre nom',
    prefixIcon: Icon(Icons.person),
    border: OutlineInputBorder(),
  ),
  onChanged: (value) {
    print('Texte: value');
  },
)

Pour récupérer et contrôler la valeur, utilise un TextEditingController.

Widgets de navigation : structure de l'app

Je te montre comment structurer ton écran correctement - c'est la fondation de toute bonne app Flutter.

Scaffold : Structure d'écran

Scaffold fournit la structure de base d'un écran Material Design avec AppBar, body, FAB, etc.

Pourquoi l'utiliser ? C'est la base de presque tous les écrans Flutter.

Scaffold(
  appBar: AppBar(
    title: Text('Mon App'),
  ),
  body: Center(
    child: Text('Contenu'),
  ),
  floatingActionButton: FloatingActionButton(
    onPressed: () {},
    child: Icon(Icons.add),
  ),
)

Conseils de performance et bonnes pratiques

Je te donne les astuces que tu dois vraiment appliquer pour que ton app reste rapide et clean.

1. Utilise const autant que possible

Les widgets const sont créés une seule fois et réutilisés, économisant mémoire et temps de build.

const Text('Texte constant')
const Icon(Icons.home)
const SizedBox(height: 20)

2. Extrais les widgets complexes

Au lieu de tout mettre dans build(), extrais des morceaux en widgets ou méthodes privées.

Widget _buildHeader() {
  return Container(
    padding: EdgeInsets.all(16),
    child: Text('Header'),
  );
}

3. Choisis le bon widget de layout

  • Juste espacement ? → SizedBox

  • Juste padding ? → Padding

  • Décoration nécessaire ? → Container

4. ListView.builder pour grandes listes

Toujours utiliser .builder() pour les listes avec beaucoup d'éléments. Il ne crée que ce qui est visible.

Conclusion

Les widgets sont l'essence de Flutter. Avec ceux qu'on a vus aujourd'hui, tu as tout ce qu'il faut pour créer des interfaces magnifiques et performantes.

Points clés :

  • Tout est widget : Composition de widgets simples en complexes

  • StatelessWidget : Par défaut, plus performant

  • StatefulWidget : Quand tu as besoin d'état mutable

  • Layout : Row, Column, Stack sont les bases

  • Performance : Utilise const, extrais les widgets, .builder() pour listes

Avec ces fondations solides, tu es prêt à créer n'importe quelle interface Flutter !


Ressources :


Articles connexes

Commentaires (2)

Laisser un commentaire