🛢️Parcours Fioul GroupéCours — Flutter, les bases (FR)
Accueil › Cours Flutter — les bases
📱 Cours de base — en français

Flutter, les bases

Un cours court et progressif pour créer sa première application mobile avec Flutter et le langage Dart, dans l'esprit des tutoriels simples : une notion par section, la syntaxe, un exemple et le rendu. On construit petit à petit un mini-écran de liste de produits.

1 Notion

Qu'est-ce que Flutter ?

Flutter est un framework de Google pour créer des applications multiplateformes (Android, iOS, web, desktop) à partir d'un seul code. Il utilise le langage Dart. Son principe fondateur : tout est widget — chaque élément de l'interface (texte, bouton, marge, écran entier) est un widget.

À retenir — en Flutter, on ne « dessine » pas l'écran : on décrit une arborescence de widgets, et Flutter s'occupe du rendu.
2 Notion

Créer & lancer un projet

On crée un projet avec la commande flutter create, puis on le lance sur un émulateur ou un téléphone branché avec flutter run.

Commandes

flutter create fioul_app      # crée le projet
cd fioul_app
flutter run                   # lance sur l'appareil/émulateur

Fichiers importants

lib/main.dart          # le point d'entrée de l'application
pubspec.yaml           # dépendances (paquets) et ressources
Hot reload — pendant que l'appli tourne, enregistre le fichier (ou tape r dans la console) : le changement apparaît en moins d'une seconde.
3 Notion

Tout est widget

Un widget décrit une partie de l'interface. Des widgets simples : Text (du texte), Icon (une icône), Image. Des widgets « contenants » reçoivent d'autres widgets via leur propriété child (un enfant) ou children (plusieurs).

Exemples de widgets

Text('Bonjour')
Icon(Icons.local_gas_station)
Padding(
  padding: EdgeInsets.all(16),   // une marge de 16 px
  child: Text('Avec une marge'),  // son enfant
)
À retenir — l'interface est un arbre de widgets : un widget en contient d'autres, qui en contiennent d'autres… C'est la brique de base de tout Flutter.
4 Notion

Une première application

On lance l'appli avec runApp(). MaterialApp pose le style Material ; Scaffold fournit la structure d'un écran (barre en haut AppBar, corps body).

lib/main.dart

import 'package:flutter/material.dart';

void main() => runApp(const MonAppli());

class MonAppli extends StatelessWidget {
  const MonAppli({super.key});
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: const Text('Fioul Groupé')),
        body: const Center(child: Text('Bonjour !')),
      ),
    );
  }
}

Rendu

Fioul Groupé
Bonjour !
À retenir — la méthode build() renvoie l'arbre de widgets à afficher. Center centre son enfant à l'écran.
5 Notion

Organiser l'écran (layout)

Deux widgets essentiels pour placer les éléments : Column (les empile verticalement) et Row (les aligne horizontalement). Ils prennent une liste children.

Exemple — une colonne

Column(
  children: const [
    Text('Campagne Ladignac'),
    Text('Volume : 4200 L'),
    Text('Prix : 1,02 €/L'),
  ],
)

Rendu

Détail campagne
Campagne Ladignac
Volume : 4200 L
Prix : 1,02 €/L
Astuce — mainAxisAlignment et crossAxisAlignment règlent l'alignement dans une Column/Row. Expanded fait qu'un enfant occupe l'espace restant.
6 Notion

Stateless vs Stateful

Un StatelessWidget est figé (il ne change pas après affichage). Un StatefulWidget a un état qui peut évoluer : on appelle setState() pour dire à Flutter de redessiner l'écran.

Exemple — un compteur (état qui change)

class Compteur extends StatefulWidget {
  const Compteur({super.key});
  @override
  State<Compteur> createState() => _CompteurState();
}

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

  @override
  Widget build(BuildContext context) {
    return Column(children: [
      Text('Litres : $_valeur'),
      ElevatedButton(
        onPressed: () => setState(() => _valeur += 100),
        child: const Text('+100 L'),
      ),
    ]);
  }
}
À retenir — sans setState(), modifier _valeur ne rafraîchit pas l'écran. C'est setState() qui déclenche un nouveau build().
7 Notion

Afficher une liste

ListView affiche une liste défilante. ListView.builder construit les éléments à la demande : idéal pour une liste venant de données (ex. des campagnes).

Exemple

final produits = ['Fioul 500L', 'Fioul 1000L', 'Fioul 2000L'];

ListView.builder(
  itemCount: produits.length,
  itemBuilder: (context, i) => ListTile(
    leading: const Icon(Icons.local_gas_station),
    title: Text(produits[i]),
  ),
)

Rendu

Produits
⛽ Fioul 500L
⛽ Fioul 1000L
⛽ Fioul 2000L
À retenir — ListTile est un widget prêt à l'emploi pour une ligne de liste (icône, titre, sous-titre, action).
9 Notion

Appeler une API (HTTP)

Le paquet http permet d'interroger une API REST (comme celle construite avec Spring). Les appels réseau sont asynchrones : on utilise async/await.

Ajouter le paquet (pubspec.yaml)

dependencies:
  http: ^1.2.0

Récupérer des données et les transformer

import 'package:http/http.dart' as http;
import 'dart:convert';

Future<List> chargerCampagnes() async {
  final url = Uri.parse('http://10.0.2.2:8080/api/campagnes');
  final reponse = await http.get(url);
  if (reponse.statusCode == 200) {
    return jsonDecode(reponse.body);   // JSON → liste Dart
  }
  throw Exception('Erreur de chargement');
}
Émulateur Android — pour joindre une API sur ton PC, l'adresse est 10.0.2.2 (et non localhost, qui désignerait l'émulateur lui-même).
Afficher le résultat — on combine souvent FutureBuilder (gère chargement/erreur/données) avec ListView.builder pour afficher la liste reçue de l'API.
10 Notion

Un formulaire

Un TextField saisit du texte ; un TextEditingController en récupère la valeur. Un bouton déclenche l'action (ex. envoyer en POST à l'API).

Exemple — saisir une quantité de litres

final _litres = TextEditingController();

Column(children: [
  TextField(
    controller: _litres,
    keyboardType: TextInputType.number,
    decoration: const InputDecoration(labelText: 'Litres'),
  ),
  ElevatedButton(
    onPressed: () {
      final valeur = _litres.text;   // la saisie
      // ... envoyer à l'API : POST /campagnes/{id}/commandes
    },
    child: const Text('Rejoindre la campagne'),
  ),
])
Le lien avec le projet — ces bases suffisent à afficher les campagnes et à s'y inscrire. Pour l'appli complète, écran par écran (modèle → service → liste → détail → état → formulaire → auth JWT), voir le guide pas à pas.
+ Pour aller plus loin

Ressources Flutter

← Cours Spring Boot