Menu
CoddyTech

Provider: Consumer

Parte da seção Gerenciamento de estado do Journey de Flutter da Coddy. Lição 12 de 27.

Aqui, o provider é criado dentro do próprio build de MyApp, e o mesmo build solicita a lâmpada logo abaixo. O app exibe um erro: context pertence a MyApp, que fica acima do provider, e um widget só consegue encontrar providers que estejam acima dele.

Um Consumer resolve isso. Ele é um widget, então fica abaixo do provider, e seu builder recebe um context novo e o próprio modelo:

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

O builder é executado novamente toda vez que a lâmpada chama notifyListeners(), como um widget que a observa. Dentro dele, você pode chamar os métodos do modelo diretamente em lamp: onPressed: () => lamp.toggle().

Um Consumer também reconstrói apenas o conteúdo que envolve, então envolver a parte que muda mantém o restante da tela estático. Na maioria dos apps, você usará context.watch em um widget próprio e recorrerá a Consumer quando estiver no mesmo build que o provider.

challenge icon

Desafio

Médio

O app abre com um erro. Coloque as partes da lâmpada dentro de um Consumer:

  • Envolva a Column em um Consumer<Lamp> e retorne a Column do builder.
  • Dentro dele, use o lamp do builder para o ícone, o texto e o botão.

Experimente você mesmo

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 iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Gerenciamento de estado

Pratique por conta própria: Compilador de Flutter online