Menu
CoddyTech

Provider : Consumer

Fait partie de la section Gestion d’état du Journey Flutter de Coddy. Leçon 12 sur 27.

Ici, le fournisseur est créé dans le propre build de MyApp, et ce même build demande la lampe juste en dessous. L’application affiche une erreur : context appartient à MyApp, qui se trouve au-dessus du fournisseur, et un widget ne peut trouver que les fournisseurs situés au-dessus de lui.

Un Consumer résout ce problème. C’est un widget, il se trouve donc en dessous du fournisseur, et son builder reçoit un nouveau context ainsi que le modèle lui-même :

Consumer<Lamp>(
  builder: (context, lamp, child) {
    return Text(lamp.isOn ? 'On' : 'Off');
  },
)

Le builder s’exécute de nouveau chaque fois que la lampe appelle notifyListeners(), comme un widget qui la surveille. À l’intérieur, vous pouvez appeler directement les méthodes du modèle sur lamp : onPressed: () => lamp.toggle().

Un Consumer ne reconstruit aussi que ce qu’il enveloppe, donc envelopper la partie qui change permet de garder le reste de l’écran inchangé. Dans la plupart des applications, vous utiliserez context.watch dans un widget dédié, et vous aurez recours à Consumer lorsque vous vous trouvez dans le même build que le fournisseur.

challenge icon

Défi

Moyen

L’application s’ouvre sur une erreur. Place les éléments de la lampe dans un Consumer :

  • Enveloppe le Column dans un Consumer<Lamp> et retourne le Column depuis son builder.
  • À l’intérieur, utilise le lamp du builder pour l’icône, le texte et le bouton.

Essayez vous-même

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class Lamp extends ChangeNotifier {
  bool _isOn = false;

  bool get isOn => _isOn;

  void toggle() {
    _isOn = !_isOn;
    notifyListeners();
  }
}

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

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => Lamp(),
      child: MaterialApp(
        debugShowCheckedModeBanner: false,
        home: Scaffold(
          appBar: AppBar(title: const Text('Lamp')),
          body: Center(
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: [
                Icon(
                  context.watch<Lamp>().isOn ? Icons.lightbulb : Icons.lightbulb_outline,
                  size: 96,
                  color: context.watch<Lamp>().isOn ? Colors.amber : Colors.grey,
                ),
                Text(context.watch<Lamp>().isOn ? 'The lamp is on' : 'The lamp is off'),
                const SizedBox(height: 16),
                ElevatedButton(
                  onPressed: () => context.read<Lamp>().toggle(),
                  child: const Text('Switch'),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Gestion d’état

Entraînez-vous par vous-même : Compilateur Flutter en ligne