Bloc Usage Without RxDart in Flutter

16-03-2020

Events

abstract class CounterEvent {}

class IncrementEvent extends CounterEvent{}
class DecrementEvent extends CounterEvent{}

Bloc Class

import 'dart:async';

import 'package:fluttertemplate/blocs/bloc.dart';

import 'counter_event.dart';
/// More Detail:
/// https://www.didierboelens.com/2018/08/reactive-programming-streams-bloc/
/// https://pub.dev/documentation/rxdart/latest/
/// https://blog.soshace.com/understanding-flutter-bloc-pattern/
class CounterBloc extends Bloc {
  int _counter = 0;
  final _counterStateController = StreamController<int>();

  Stream<int> get counterStream => _counterStateController.stream;
  final _counterEventController = StreamController<CounterEvent>();

  Sink<CounterEvent> get counterEventSink => _counterEventController.sink;

  CounterBloc() {
    _counterEventController.stream
        //.where((value) => value == IncrementEvent())//where clause :)
        .listen(_mapEventToState);
  }

  void _mapEventToState(CounterEvent event) {
    if (event is IncrementEvent)
      _counter++;
    else
      _counter--;
    _counterStateController.sink.add(_counter);
  }

  @override
  void dispose() {
    _counterStateController.close();
    _counterEventController.close();
  }
}

Usage

class _MyHomePageState extends State<MyHomePage> {
  final _bloc = new CounterBloc();

  @override
  Widget build(BuildContext context) {
    // This method is rerun every time setState is called, for instance as done
    // by the _incrementCounter method above.
    //
    // The Flutter framework has been optimized to make rerunning build methods
    // fast, so that you can just rebuild anything that needs updating rather
    // than having to individually change instances of widgets.
    return Scaffold(
      appBar: AppBar(
        // Here we take the value from the MyHomePage object that was created by
        // the App.build method, and use it to set our appbar title.
        title: Text(widget.title),
      ),
      body: Center(
          // Center is a layout widget. It takes a single child and positions it
          // in the middle of the parent.
          child: StreamBuilder(
            stream: _bloc.counterStream,
            builder: (BuildContext context, AsyncSnapshot<int> snapshot) {
              if(!snapshot.hasData){
                return Center(child: CircularProgressIndicator(),);
              }
              return Column(
                mainAxisAlignment: MainAxisAlignment.center,
                children: <Widget>[Text('${snapshot.data}')],
              );
            },
      )),
      floatingActionButton: FloatingActionButton(
        onPressed: () => _bloc.counterEventSink.add(IncrementEvent()),
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }

  @override
  void dispose() {
    _bloc.dispose();
    super.dispose();
  }
}

© 2019 All rights reserved. Codesenior.COM