Bloc State Management para iniciantes (Parte 2) — Flutter

Tempo de leitura: 2 minutes

Configurando um aplicativo de contador simples

Para entender melhor o padrão de gerenciamento de estado do bloco, vamos criar um exemplo simples de aplicativo contador. Nosso aplicativo terá dois botões, um para incrementar o contador e outro para decrementá-lo. O valor atual do contador será exibido na tela.

Primeiro, certifique-se de ter essas dependências em seu arquivo pubspec.yaml:

dependencies:
  flutter:
    sdk: flutter
  bloc: ^8.1.1
  flutter_bloc: ^8.1.2

Agora, vamos começar a projetar nossa IU, pois já criamos o arquivo counter_view.dart e começaremos a codificar nele. Você pode obter o código-fonte mencionado em parte — 1 artigo.

Nosso counter_view.dart conterá a interface do usuário para nosso aplicativo contador. Neste arquivo, definiremos nosso widget CounterPage que usa o widget BlocProvider do pacote flutter_bloc para fornecer o CounterBloc para seus widgets filhos:

import 'package:blocexemplo/bloc/counter_bloc.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Counter App'),
      ),
      body: BlocProvider(
        create: (_) => CounterBloc(),
        child: const CounterView(),
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return BlocBuilder<CounterBloc, CounterState>(
      builder: (context, state) {
        return Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              const Text('Counter', style: TextStyle(fontSize: 24.0)),
              Text('${state.counterValue}', style: const TextStyle(fontSize: 36.0)),
              const SizedBox(height: 16.0),
              Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[
                  FloatingActionButton(
                    onPressed: () => context.read<CounterBloc>().add(IncrementCounter()),
                    child: const Icon(Icons.add),
                  ),
                  const SizedBox(width: 16.0),
                  FloatingActionButton(
                    onPressed: () => context.read<CounterBloc>().add(DecrementCounter()),
                    child: const Icon(Icons.remove),
                  ),
                ],
              ),
            ],
          ),
        );
      },
    );
  }
}

Esta UI simples contém dois botões um para aumentar e outro para diminuir e no centro, há um contador que mostra o valor atual da contagem.

Este código parece difícil de entender? 🤔Vamos discutir separadamente a lógica que usei no código acima.

BlocProvider(
        create: (_) => CounterBloc(),
        child: const CounterView(),
      ),

BlocProvider é necessário para criar o Bloc ou você pode dizer para iniciar o Bloc. Você pode ver que está criando o arquivo Counter Bloc, o que significa que, onde quer que você forneça o Bloc Provider, ele simplesmente inicializará todas as suas variáveis de estado e o contexto será compartilhado com o código abaixo para usar.

BlocBuilder<CounterBloc, CounterState>(
  builder: (context, state) {
    
  },
);

O BlocBuilder é usado para mostrar as alterações na interface do usuário sempre que ele emite o estado. Você se lembra que discutimos isso? Você pode encontrá-lo no arquivo counter bloc. Para acessar a variável de estado, nós a usamos como state.counterValue e ela continuará atualizando quando atingirmos o evento de incremento ou decremento que, por fim, emitirá o estado e o ouvirá.

FloatingActionButton(
 onPressed: () => context.read<CounterBloc>().add(IncrementCounter()),
 child: const Icon(Icons.add),
)
FloatingActionButton(
  onPressed: () => context.read<CounterBloc>().add(DecrementCounter()),
  child: const Icon(Icons.remove),
),

Aqui em ambos os botões, acionamos o evento de incremento e decremento do contador que será tratado pelo nosso arquivo Bloc. Quando o usuário pressionou o botão para incrementar, então o gatilho de evento IncrementCounter() e o arquivo bloc o tratam assim.

CounterBloc() : super(CounterState.initial()) {
    on<IncrementCounter>((event, emit) => incrementCounter(event, emit));
    on<DecrementCounter>((event, emit) => decrementCounter(event, emit));
  }

Você pode ver o em IncrementCounter. é responsável por tratá-lo e retorna uma função de contador de incremento que realmente incrementará o contador.

incrementCounter(IncrementCounter event, Emitter<CounterState> emit) {
    emit(state.copyWith(counterValue: state.counterValue + 1));
  }

O mesmo vale para decrementar o contador.

Essa foi a ideia simples de usar o gerenciamento de estado do BloC no aplicativo flutter. Estarei compartilhando mais dicas para melhorar seu domínio do bloC. Até agora, tente aprender com ele e compartilhe suas críticas honestas.

URL do Projeto Github: