Using BLoC (Business Logic Component) in a Flutter application helps you separate presentation and business logic, making your app more scalable and maintainable. Here’s a step-by-step guide to using the BLoC pattern in Flutter using the flutter_bloc package.
Step-by-Step Guide to Use BLoC in Flutter
Prerequisites
Make sure you have:
- Flutter SDK installed
- Basic Flutter knowledge
- A Flutter project set up
Step 1: Add Dependencies
In your pubspec.yaml file, add:
dependencies:
flutter:
sdk: flutter
flutter_bloc: ^8.1.3 # or the latest version
equatable: ^2.0.5 # for value comparison (optional, but recommended)
Then run:
flutter pub get
Step 2: Define Your Model (if needed)
Create a simple model. Example: counter_model.dart (for a counter app, optional):
class Counter {
final int value;
Counter(this.value);
}
Step 3: Define Events
Create an abstract class for events: counter_event.dart
abstract class CounterEvent {}
class IncrementEvent extends CounterEvent {}
class DecrementEvent extends CounterEvent {}
Step 4: Define States
Create a class for state: counter_state.dart
import 'package:equatable/equatable.dart';
class CounterState extends Equatable {
final int counter;
const CounterState(this.counter);
@override
List<Object> get props => [counter];
}
Step 5: Create the BLoC
Create the business logic component: counter_bloc.dart
import 'package:flutter_bloc/flutter_bloc.dart';
import 'counter_event.dart';
import 'counter_state.dart';
class CounterBloc extends Bloc<CounterEvent, CounterState> {
CounterBloc() : super(const CounterState(0)) {
on<IncrementEvent>((event, emit) {
emit(CounterState(state.counter + 1));
});
on<DecrementEvent>((event, emit) {
emit(CounterState(state.counter - 1));
});
}
}
Step 6: Provide the BLoC to the App
Wrap your app (or a part of it) in a BlocProvider. In main.dart:
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'counter_bloc.dart';
import 'counter_event.dart';
import 'counter_state.dart';
void main() {
runApp(
BlocProvider(
create: (context) => CounterBloc(),
child: MyApp(),
),
);
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: CounterPage(),
);
}
}
Step 7: Use Bloc in Your UI
Create the UI in counter_page.dart:
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'counter_bloc.dart';
import 'counter_event.dart';
import 'counter_state.dart';
class CounterPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final counterBloc = BlocProvider.of<CounterBloc>(context);
return Scaffold(
appBar: AppBar(title: Text('Flutter BLoC Example')),
body: Center(
child: BlocBuilder<CounterBloc, CounterState>(
builder: (context, state) {
return Text(
'Counter Value: ${state.counter}',
style: TextStyle(fontSize: 24),
);
},
),
),
floatingActionButton: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
FloatingActionButton(
heroTag: 'decrement',
onPressed: () => counterBloc.add(DecrementEvent()),
child: Icon(Icons.remove),
),
SizedBox(width: 10),
FloatingActionButton(
heroTag: 'increment',
onPressed: () => counterBloc.add(IncrementEvent()),
child: Icon(Icons.add),
),
],
),
);
}
}
Summary of Concepts
| Concept | Description |
|---|---|
| Event | User actions or app triggers (e.g., button press) |
| State | Data to represent the UI at a given time |
| Bloc | Business logic handling events and emitting states |
| BlocProvider | Injects BLoC into the widget tree |
| BlocBuilder | Rebuilds UI based on state changes |
Bonus: BlocListener and BlocConsumer
- Use
BlocListenerfor side effects like navigation, snackbars. - Use
BlocConsumerif you need bothBlocBuilderandBlocListener.
That’s It!
You’ve successfully integrated BLoC into your Flutter app 🎉