Here's a snippet from my old code, but I highly recommend using bloc and flutter_bloc, it removes a lot of boilerplate code, it's safer and just more known, VSCode plugin handles a lot of code-generation too.
class VotesBloc {
final List<VoteCount> voteGroups = []; // initial state
// broadcasting stream so it can be used multiple times
final _controlStateController = StreamController<List<VoteCount>>.broadcast();
StreamSink<List<VoteCount>> get _incomingVote => _controlStateController.sink;
Stream<List<VoteCount>> get outgoingVote => _controlStateController.stream;
final _votesEventController = StreamController<VoteEvent>.broadcast();
Sink<VoteEvent> get votesEventSink => _votesEventController.sink;
VotesBloc() {
_votesEventController.stream.listen(_mapValuesToState);
}
void _mapValuesToState(VoteEvent event) {
if (event is NewVoteEvent) {
// handle this state
} else if (event is VoteChangedEvent) {
// handle this state
}
_incomingVote.add(voteGroups);
}
void dispose() {
_controlStateController.close();
_votesEventController.close();
}
}
abstract class VoteEvent {
final Vote _vote;
VoteEvent(this._vote);
}
class NewVoteEvent extends VoteEvent {
NewVoteEvent(Vote vote) : super(vote);
}
class VoteChangedEvent extends VoteEvent {
VoteChangedEvent(Vote vote) : super(vote);
}
class VoteCount {
final String value;
int counter;
List<Vote> votes;
VoteCount(this.value, {this.counter, this.votes});
}
And builder function:
StreamBuilder<List<VoteCount>>(
stream: votesBloc.outgoingVote,
initialData: votesBloc.voteGroups,
builder: (BuildContext context, AsyncSnapshot<List<VoteCount>> snapshot) {
return Widget();
}
)
Use bloc outside:
votesBloc.votesEventSink.add(VoteChangedEvent(vote));