Event Bus em Flutter

Tempo de leitura: 3 minutes

Olá 👋, estou de volta com um novo artigo, que é sobre EventBus e por que o usamos no Flutter. O que vou abordar neste artigo?

O que é EventBus?
O que um EventBus faz?
Por que precisamos do EventBus?
Como usar o EventBus

 

O que é EventBus?

EventBus é uma forma de diferentes partes de um programa se comunicarem sem saber muito umas sobre as outras. É como um quadro de avisos onde uma parte do programa pode postar uma mensagem e outras partes podem escolher ouvir essa mensagem e reagir a ela. Isto torna o programa mais flexível e mais fácil de alterar porque cada parte pode trabalhar de forma independente, sem ter que saber muito sobre as outras.

Conseqüentemente, EventBus é um padrão arquitetônico derivado dos primeiros dias da arquitetura orientada a serviços. É um padrão de publicação/assinatura que ajuda na dissociação. E é necessário quando temos vários MVC para lidar.

 

O que um EventBus faz?

O EventBus permite a comunicação central para a qual os ouvintes assinam eventos e os editores disparam os eventos. Ao usar o EventBus, não há necessidade de criar vários ouvintes e acompanhá-los. Por exemplo, um componente pode enviar um evento para um barramento de eventos e vários componentes escutam um evento e podem reagir a ele.

 

Por que precisamos do EventBus?

Para compartilhar dados de um componente para outro, temos vários métodos. Mas o problema durante isso é a manipulação de dados. Às vezes, ao passar de um componente para outro, os dados são manipulados. E por causa disso dados errados são processados. Para superar esse problema, o EventBus é usado.

 

Como usar o EventBus?

  • Crie uma instância do EventBus e disponibilize-a para outras classes.
  • Defina qualquer classe como um evento
  • Registrar ouvintes para eventos específicos/todos
  • Evento de incêndio

Abaixo como usar EventBus em seu projeto. E para isso vou usar o pacote https://pub.dev/packages/event_bus.

 

1 – Crie uma instância do EventBus e disponibilize-a para outras classes.

import 'package:event_bus/event_bus.dart';
EventBus eventBus = EventBus();

No código acima, estou criando uma instância global de EventBus para que a escuta ou disparo de um evento se torne acessível.

 

2 – Defina qualquer classe como um Evento

Agora, crie um evento conforme sua necessidade. Aqui, criei ThemeChangeEvent para alterar o tema do aplicativo. A única coisa que você precisa fazer é disparar e ouvir esse evento através do EventBus.

class ThemeChangeEvent {
 String colorStr;
 ThemeChangeEvent(this.colorStr);
}

 

3 – Registre ouvintes para eventos específicos/todos

_colorStreamSub = eventBus.on<ThemeChangeEvent>().listen((event) {
  Color color = getColor(event.colorStr);
   setState(() { 
       _primaryColor = color; 
   });
});

O código acima ilustra como registrar um ouvinte para um evento específico. Sempre que um evento for disparado para alterar o tema do aplicativo, ele ouvirá as alterações e atualizará a UI.

 

4 – Evento Fire

Agora, basta disparar o evento após receber a entrada, e abaixo está o código para disparar um evento usando EventBus.

eventBus.fire(ThemeChangeEvent(color.text));

Dê uma olhada na essência abaixo para ter mais ideia de como implementei um EventBusWidget para este tutorial.

import 'dart:async';

import 'package:event_bus/event_bus.dart';
import 'package:event_bus_tutorial/event/theme_change_event.dart';
import 'package:flutter/material.dart';

EventBus eventBus = EventBus();

class EventBusWidget extends StatefulWidget {
  const EventBusWidget({Key? key}) : super(key: key);

  @override
  _EventBusWidgetState createState() => _EventBusWidgetState();
}

class _EventBusWidgetState extends State<EventBusWidget> {
  TextEditingController color =  TextEditingController();
  Color? _primaryColor;
  StreamSubscription? _colorStreamSub;
  static const Color primaryColor = Color(0xff7C46B3);

  static Color getColor(String colorStr) {
      if (colorStr.substring(0, 1) != "#") {
        return primaryColor;
      }
      String substring = colorStr.substring(1, colorStr.length);
      return Color(int.parse('0xff' + substring));
  }

  @override
  void dispose() {
    super.dispose();
    _colorStreamSub?.cancel();
  }

  @override
  void initState() {
    super.initState();
    _colorStreamSub = eventBus.on<ThemeChangeEvent>().listen((event) {
      Color color = getColor(event.colorStr);
      setState(() {
        _primaryColor = color;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: _primaryColor,
      appBar: AppBar(
        title: const Text("Event Bus"),
      ),
      body: Center(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Container(
              margin: const EdgeInsets.only(left: 10, right: 10),
                height: 48.00,
                width: 343.00,
                child: TextFormField(
                    controller: color,
                    decoration: InputDecoration(
                        hintText:
                        "Theme Color HexCode",
                        hintStyle: const TextStyle(
                          fontSize: 16
                        ),
                        enabledBorder: OutlineInputBorder(
                            borderRadius: BorderRadius.circular(
                                5.00),
                            borderSide: const BorderSide(
                                color: Colors.blue,
                                width: 1)),
                        focusedBorder: OutlineInputBorder(
                            borderRadius: BorderRadius.circular(5.00),
                            borderSide: const BorderSide(color: Colors.blue, width: 1)),
                        isDense: true,
                        contentPadding: const EdgeInsets.only(top: 16.80, bottom: 16.80, left: 10)),
                    style: const TextStyle(color: Colors.black, fontSize: 12.0, fontFamily: 'Poppins', fontWeight: FontWeight.w400))),
            Container(
              padding: const EdgeInsets.all(18.0),
              width: 143.00,
              child: ElevatedButton(
                  onPressed: () {
                    eventBus.fire(ThemeChangeEvent(color.text));
                  },
                  child: const Text("Enter"),
                ),
            ),
          ],
        ),
      ),
    );
  }
}