Skip to content

Instantly share code, notes, and snippets.

@andrewackerman
Created May 6, 2019 18:29
Show Gist options
  • Save andrewackerman/5b8d7adabe092c10741cbfacff653f3f to your computer and use it in GitHub Desktop.
Save andrewackerman/5b8d7adabe092c10741cbfacff653f3f to your computer and use it in GitHub Desktop.
// Widget class
@override initState() {
AppStateBloc.stream.listen(updateWidget); // Subscribe to the state stream
}
void updateWidget(AppState obj) {
setState(() {}); // Trigger rebuild
}
void mutateState() { // Simulates doing something that would cause the state to change
AppStateBloc.dispatch('changeInteger', 2);
}
@override Widget build(BuildContext cxt) {
final state = AppStateBloc.currentState; // Get the current state
// ...
// Build widget based on the values from state
}
// ..........
// AppStateBloc class
// The data object representing the current state
// This object can have any number of fields of all sorts of types
AppState _currentState;
AppState get currentState => _currentState;
_StreamController<AppState> _controller; // Responsible for piping items to the stream
Stream<AppState> get stream => _controller.stream; // Convenience getter so widgets can listen to the stream
// This method handles change requests to the stream
void dispatch(String label, dynamic value) async {
await for (var value in _updateState()) {
// For every value we get back from _updateState, change the current state and fire the stream event
currentState = value;
_controller.add(value);
}
}
// An internal helper method for handling state change requests
Stream<AppState> _updateState(String label, dynamic value) async* {
// Handle the state change depending on the label passed
//
// Note that some changes involve updating the state object multiple times,
// causing the stream to receive multiple updates from a single call.
switch (label) {
case 'changeInteger':
yield currentState.copyWith(intValue: value);
break;
case 'changeString':
yield currentState.copyWith(stringValue: value);
break;
case 'changeBool':
yield currentState.copyWith(boolValue: value);
break;
case 'makeComplexChanges':
yield currentState.copyWith(complexValueA: value.a);
yield currentState.copyWith(complexValueB: value.b);
yield currentState.copyWith(complexValueC: value.c);
break;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment