Tiny predictable opinionated state management package with prebuilt concurrency handlers that implement the Business Logic Component design pattern without complexity of flutter_bloc.
ChangeNotifier
, Stream
and
InheritedNotifier
for scopingListenableBuilder
,
InheritedWidget/InheritedNotifier
, StreamBuilder
, etc..flutter pub add streamed_controller
class TestControllerBase extends StreamedController<int> {
TestControllerBase() : super(initialState: 0, eventHandler: ConcurrentConcurrencyHandler());
Future<void> incrementAwaitable() => handle(() async* {
await Future.delayed(const Duration(seconds: 1));
yield state+1;
}());
}
final $controller = TestControllerBase();
ListenableBuilder(
listenable: $controller,
builder: (context, child) => Text(
'${$controller.state}',
style: Theme.of(context).textTheme.headlineMedium,
))
FloatingActionButton(
onPressed: $controller.increment,
tooltip: 'Async increment',
child: const Icon(Icons.add),
)
To create your own controller observer, that watches for all controller's lifecycles, you need to extend StreamedControllerObserver and override its methods:
onCreate
onDispose
onError
onStateChanged
Then you need to assign a static variable observer
to your observer object in
the initialization (or other place) of your code
StreamedController.observer = MyCoolObserver();
By default, you can try logger that uses internal dart:developer
log
method
Pass it like this:
StreamedController.observer = StreamedControllerObserver.dartLog();
StreamedControllerObserver example:
class _TestControllerObserver extends StreamedControllerObserver {
@override
void onCreate(StreamedController<Object> controller) =>
log('${controller.runtimeType} created');
@override
void onDispose(StreamedController<Object> controller) =>
log('${controller.runtimeType} disposed');
@override
void onError(StreamedController<Object>? controller, Object? error,
StackTrace stackTrace) =>
log('${controller.runtimeType} got error: $error');
@override
void onStateChanged(StreamedController<Object> controller, Object prevState,
Object nextState) =>
log('${controller.runtimeType} state updated, new state: $nextState');
}
StreamedController
exposes stateChanges
lazy Stream<State>
that emits new
state to it listeners, basing on Stream API In general, you won't have to use
this stream for rebuilding states or etc, because you have all features from
ChangeNotifier
API
stateChanges
stream is lazy, which means it doesn't create until first call
2023, Archie Kitsuniru (kitsuniru)