Skip to content

Instantly share code, notes, and snippets.

@YazeedAlKhalaf
Last active December 14, 2021 14:39
Show Gist options
  • Save YazeedAlKhalaf/76281be54c0e6ce477e2af0d280be4f6 to your computer and use it in GitHub Desktop.
Save YazeedAlKhalaf/76281be54c0e6ce477e2af0d280be4f6 to your computer and use it in GitHub Desktop.
counter bloc for medium blog
import 'dart:async';
// those are the events that the user can do,
// aka `add` to the bloc and manipulate the bloc state.
enum CounterEvent {
increment,
decrement,
reset,
}
class CounterBloc {
late int _counter;
final _stateStreamController = StreamController<int>();
final _eventStreamController = StreamController<CounterEvent>();
// should only be used inside the bloc.
StreamSink<int> get _stateSink => _stateStreamController.sink;
// this will be listened to in the ui to change the ui accordingly.
Stream<int> get stateStream => _stateStreamController.stream;
// this will be used to interact with the bloc and manipulate it from the ui.
StreamSink<CounterEvent> get eventSink => _eventStreamController.sink;
// should only be used inside the bloc.
Stream<CounterEvent> get _eventStream => _eventStreamController.stream;
CounterBloc() {
// this is the inital state.
_counter = 0;
// here we listen to the events stream and run some logic on the state
// according to the event provided.
_eventStream.listen((CounterEvent event) {
if (event == CounterEvent.increment) {
_counter++;
} else if (event == CounterEvent.decrement) {
_counter--;
} else if (event == CounterEvent.reset) {
_counter = 0;
}
// the new counter is added to state after the manipulation.
// this will be reflected in the ui.
_stateSink.add(_counter);
});
}
}
// ... other widgets in the column.
Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
IconButton(
onPressed: () {
// add decrement event to counter bloc.
_counterBloc.eventSink.add( // add this line
CounterEvent.decrement, // add this line
); // add this line
},
icon: const Icon(
Icons.remove_rounded,
),
),
IconButton(
onPressed: () {
// add reset event to counter bloc.
_counterBloc.eventSink.add( // add this line
CounterEvent.reset, // add this line
); // add this line
},
icon: const Icon(
Icons.restore_rounded,
),
),
IconButton(
onPressed: () {
// add increment event to counter bloc.
_counterBloc.eventSink.add( // add this line
CounterEvent.increment, // add this line
); // add this line
},
icon: const Icon(
Icons.add_rounded,
),
),
],
),
// the rest of the build method ...
// ... stateful widget and other stuff.
class _CounterScreenState extends State<CounterScreen> {
late final CounterBloc _counterBloc; // add this line
@override
void initState() {
super.initState();
// initialze counter bloc.
_counterBloc = CounterBloc(); // add this line
}
// build method and other stuff...
}
// ... other widgets in the column.
StreamBuilder<int>(
stream: _counterBloc.stateStream,
builder: (BuildContext context, AsyncSnapshot<int> snapshot) {
final int counter = snapshot.data ?? 0;
return Text(
"$counter",
style: const TextStyle(
color: Colors.black54,
fontWeight: FontWeight.bold,
fontSize: 48,
),
textAlign: TextAlign.center,
);
},
),
// other widgets in the column ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment