1. La composition déclarative des interfaces

Dans Flutter, chaque élément visible ou structurel est un Widget : un bouton, un texte, une image, mais également une marge intérieure (Padding), un alignement (Center) ou un thème colorimétrique (Theme). L’interface utilisateur est une fonction pure de l’état : UI = f(State).

2. Le composant immuable : StatelessWidget

Un StatelessWidget décrit une portion d’interface dont les propriétés visuelles sont entièrement définies à la création et ne changent jamais de manière autonome au fil du temps. Sa méthode build() est pure et idempotente :

import 'package:flutter/material.dart';

class EnTeteCampus extends StatelessWidget {
    final String ville;
    final int nbEtudiants;

    const EnTeteCampus({
        super.key, 
        required this.ville, 
        required this.nbEtudiants
    });

    @override
    Widget build(BuildContext context) {
        return Container(
            padding: const EdgeInsets.all(16.0),
            color: Colors.blueGrey.shade50,
            child: Text(
                'Campus Éducasuisse de $ville ($nbEtudiants apprenants)',
                style: Theme.of(context).textTheme.titleMedium,
            ),
        );
    }
}

3. Le composant dynamique : StatefulWidget et son cycle de vie

Un StatefulWidget se compose de deux classes : le widget immuable lui-même et sa classe d’état mutable State<T>. Lorsque l’état change, l’appel à setState(() { ... }) signale à Flutter qu’il doit réexécuter la méthode build() pour actualiser l’affichage.

Les étapes clés du cycle de vie d’un état comprennent : initState() (initialisation unique), didChangeDependencies(), build() (dessin) et dispose() (libération impérative des contrôleurs et minuteurs).

Synthèse pédagogique : N’abusez pas des StatefulWidget au sommet de votre application : confinez la mutabilité au niveau le plus bas possible de l’arborescence de widgets pour préserver les performances de rendu.