SingleLiveEvent pattern implementation for Cubit and Bloc
The abstractions on Cubit and Bloc and Flutter Widget that make it easy to add UI Effects to the BLoC state management using [package:bloc](https://pub.dev/packages/bloc).
Usage
Lets take a look at how to use mixin Effects
or class CubitWithEffects
to dispatch effects from CounterCubit
to
a CounterPage
and react on them with BlocEffectListener
.
ui_effect.dart
abstract class UiEffect {}
class ShowBottomSheet implements UiEffect {
const ShowBottomSheet({required this.counterValue});
final int counterValue;
}
counter_cubit.dart
class CounterCubit extends Cubit<int> with Effects<UiEffect> {
CounterCubit() : super(0);
void increment() => emit(state + 1);
void onButtonPressed() => emitEffect(ShowBottomSheet(counterValue: state));
}
or the same with the class extension:
class CounterCubit extends CubitWithEffects<int, UiEffect> {
CounterCubit() : super(0);
void increment() => emit(state + 1);
void onButtonPressed() => emitEffect(ShowBottomSheet(counterValue: state));
}
main.dart
void main() => runApp(CounterApp());
class CounterApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: BlocProvider(
create: (_) => CounterCubit(),
child: CounterPage(),
),
);
}
}
counter_page.dart
class CounterPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Counter')),
body: BlocEffectListener<CounterCubit, UiEffect>(
listener: (context, effect) {
if (effect is ShowBottomSheet) {
showBottomSheet<void>(
context: context,
builder: (c) =>
Material(
child: Container(
color: Colors.black12,
height: 150,
),
),
);
}
},
child: const Sizedbox(),
),
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.upload),
onPressed: () => context.read<CounterCubit>().onButtonPressed(),
),
);
}
}
And also BlocWithEffectsObserver
can be useful. It extends BlocObserver
and add onEffect
callback to base observing features:
app_bloc_observer.dart
class AppBlocObserver extends BlocWithEffectsObserver {
@override
void onEffect(Object effect) {
super.onEffect(effect);
debugPrint('Used effect: $effect');
}
// Other [BlocObserver] overrides
}