π What is the BLoC Pattern?
The BLoC (Business Logic Component) pattern is a state management architecture designed to separate your applicationβs business logic from the UI layer. It helps you build scalable, maintainable, and testable Flutter apps using Streams.
π How it Works:
- The UI sends Events to the BLoC.
- The BLoC processes those events and emits States.
- The UI listens to those states and rebuilds accordingly.
This pattern allows you to manage complex UI flows with multiple states in a predictable way.
π How BLoC Works (Streams & Sinks)
At the core of the BLoC pattern are:
- Streams β the output, or data you want to listen to.
- Sinks β the input, or data you want to add into the system.
β Simple Stream Example:
final _controller = StreamController();
Stream get stream => _controller.stream;
Sink get sink => _controller.sink;
void increment(int value) {
sink.add(value + 1);
}
- You push data using the
sink.add()
method. - You listen to data using the
stream.listen()
method.
In actual Flutter BLoC, the BLoC or Cubit class internally manages this mechanism.
π BLoC vs Cubit
Feature | Cubit | BLoC |
---|---|---|
Event class | β Not required | β Required |
Simplicity | β Easier to learn | β οΈ More boilerplate |
Use case | Simple & moderate logic | Complex user flows |
State changes | Direct (emit() ) |
Via events & event handlers |
Flexibility | Limited | Highly flexible |
π Cubits are a simpler form of BLoCs β great for most use-cases unless your logic depends on many types of events.
π Installing flutter_bloc
and bloc
Packages
To get started, you need to install the required dependencies:
1οΈβ£ Add to pubspec.yaml
:
dependencies:
flutter_bloc: ^8.1.3
bloc: ^8.1.2
Make sure to check for the latest versions on pub.dev.
2οΈβ£ Run:
flutter pub get
β Simple Cubit Example
Letβs build a basic counter using Cubit.
π counter_cubit.dart
import 'package:flutter_bloc/flutter_bloc.dart';
class CounterCubit extends Cubit {
CounterCubit() : super(0);
void increment() => emit(state + 1);
}
π§© Usage in UI:
BlocProvider(
create: (_) => CounterCubit(),
child: BlocBuilder<CounterCubit, int>(
builder: (context, count) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Count: \$count', style: TextStyle(fontSize: 24)),
ElevatedButton(
onPressed: () => context.read().increment(),
child: Text('Increment'),
),
],
);
},
),
);
β What Happens Here:
CounterCubit
starts with an initial state of0
.- When the button is tapped, it calls
increment()
, which emitsstate + 1
. BlocBuilder
listens to state changes and rebuilds theText
widget with the new count.
π Next Up:
Creating Events and States in BLoC β Learn how to build a full BLoC (not just Cubit) using events and states.