Menu
CoddyTech

Provider: Compartilhar um modelo

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

Elevar o estado funciona enquanto os widgets estão próximos. Quando um valor é necessário em todo o app, em duas telas, na barra superior ou no fundo de uma lista, você teria que passá-lo por todos os widgets intermediários. Provider evita isso. É um pacote: um conjunto de código que você importa com import 'package:provider/provider.dart';.

Ele tem três partes. Primeiro, um modelo: uma classe que armazena os dados e extends ChangeNotifier. Seus métodos alteram os dados e depois chamam notifyListeners():

class CupCounter extends ChangeNotifier {
  int _cups = 0;
  int get cups => _cups;

  void addCup() {
    _cups++;
    notifyListeners();
  }
}

Segundo, um ChangeNotifierProvider no alto da árvore cria o modelo uma vez e o disponibiliza para todos os widgets abaixo dele:

void main() {
  runApp(
    ChangeNotifierProvider(
      create: (context) => CupCounter(),
      child: const MyApp(),
    ),
  );
}

Terceiro, qualquer widget abaixo solicita esse modelo: context.watch<CupCounter>() para exibi-lo, context.read<CupCounter>() para chamar um método. O título e o botão abaixo recebem o mesmo contador, e nenhum dos dois recebe nada por parâmetro.

challenge icon

Desafio

Médio

Abra o aplicativo: ele mostra um erro, porque o título solicita um CupCounter e nada acima dele fornece um.

  • Em main, envolva MyApp com um ChangeNotifierProvider que cria um CupCounter.

Experimente você mesmo

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

class CupCounter extends ChangeNotifier {
  int _cups = 0;

  int get cups => _cups;

  void addCup() {
    _cups++;
    notifyListeners();
  }
}

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

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

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      debugShowCheckedModeBanner: false,
      home: HomePage(),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const CupsTitle()),
      body: const Center(child: AddCupButton()),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    final counter = context.watch<CupCounter>();
    return Text('Cups: ${counter.cups}');
  }
}

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

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: () {
        context.read<CupCounter>().addCup();
      },
      child: const Text('Another cup'),
    );
  }
}
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