Using the BLoC Architecture in Flutter
Flutter provides various architectures for effective code management and data flow in your applications. In this article, you’ll learn how to use the BLoC (Business Logic Component) architecture in Flutter to separate your application logic from the user interface and facilitate data flow.
What is Bloc?
BLoC is an architecture used for managing application logic and data flow. BLoC, which stands for “Business Logic Component,” bridges the gap between the user interface (UI) and the business logic. It processes user input, modifies data, and delivers the results to the user interface. This way, the complexity of UI code is reduced, and the business logic becomes a separate component.
The BLoC architecture consists of three main components:
- UI (User Interface): The UI is the place where the user interacts with the application. It includes buttons, input fields, lists, etc. The UI detects user actions and communicates them to the BLoC.
- BLoC (Business Logic Component): The BLoC is the component that contains the business logic and processes the incoming actions from the UI. It updates data in response to incoming actions and delivers this data back to the UI.
- Repository (Data Source): The Repository is a component that provides data for the application. It can retrieve data from a local database, a remote API, or any other data source. The BLoC communicates with the Repository and updates or fetches data when necessary.
The BLoC architecture enables a unidirectional flow of data. The UI sends actions to the BLoC, the BLoC updates the data, and the UI consumes the updated data. This ensures a structured and manageable flow of application logic and data.
Building an Application with BLoC
Developing an application using the BLoC architecture in Flutter is straightforward. Let’s walk through an example of building a counter application using the BLoC architecture:
Step 1: Project Setup and Adding Packages
Start by creating a new Flutter project and adding the necessary packages. In this example, we’ll use the flutter_bloc
package. Open the pubspec.yaml
file and add the following package dependency:
dependencies:
flutter:
sdk: flutter
flutter_bloc: ^7.0.0
Next, run the following command in the terminal at the project directory to update the packages:
flutter pub get
Step 2: Creating CounterEvent and CounterBloc
In the lib
directory, create a file named counter_event.dart
and add the following code:
abstract class CounterEvent {}
class IncrementEvent extends CounterEvent {}
class DecrementEvent extends CounterEvent {}
In this file, we define an abstract class CounterEvent
and two subclasses IncrementEvent
and DecrementEvent
. These classes represent the events we'll use in the counter application: incrementing and decrementing the counter.
Next, create another file named counter_bloc.dart
and add the following code:
import 'package:flutter_bloc/flutter_bloc.dart';
import 'counter_event.dart';
class CounterBloc extends Bloc<CounterEvent, int> {
CounterBloc() : super(0);
@override
Stream<int> mapEventToState(CounterEvent event) async* {
if (event is IncrementEvent) {
yield state + 1;
} else if (event is DecrementEvent) {
yield state - 1;
}
}
}
In this file, we create a class CounterBloc
that extends the Bloc<CounterEvent, int>
class. It takes CounterEvent
as the type for events and int
as the type for the state. We set the initial state to 0.
The mapEventToState
method is used to update the state in response to incoming events. If the event is an IncrementEvent
, we increment the state by 1. If it's a DecrementEvent
, we decrement the state by 1. We use the yield
keyword to emit the new state to the stream.
Step 3: UI Design and Using BlocProvider
Now, let’s design the user interface for the counter application. Open the main.dart
file and add the following code:
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'counter_bloc.dart';
import 'counter_event.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => CounterBloc(),
child: MaterialApp(
title: 'Counter App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
),
);
}
}
class MyHomePage extends StatelessWidget {
@override
Widget build(BuildContext context) {
final counterBloc = BlocProvider.of<CounterBloc>(context);
return Scaffold(
appBar: AppBar(
title: Text('Counter App'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'Counter Value:',
style: TextStyle(fontSize: 20),
),
BlocBuilder<CounterBloc, int>(
builder: (context, state) {
return Text(
'$state',
style: TextStyle(fontSize: 40, fontWeight: FontWeight.bold),
);
},
),
SizedBox(height: 20),
Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
RaisedButton(
onPressed: () {
counterBloc.add(IncrementEvent());
},
child: Text('Increment'),
),
SizedBox(width: 10),
RaisedButton(
onPressed: () {
counterBloc.add(DecrementEvent());
},
child: Text('Decrement'),
),
],
),
],
),
),
),
);
}
}
In this code, the MyApp
class provides the CounterBloc
using the BlocProvider
widget. The MyHomePage
widget displays the counter value and the increment/decrement buttons along with a scaffold.
The BlocBuilder
widget listens to the state of the CounterBloc
and updates the UI based on the current state. When the increment or decrement buttons are pressed, they dispatch the corresponding events to the counterBloc
.
Step 4: Running the Application
To run the application, use the following command in the terminal at the project directory:
flutter run
When the application starts, you’ll see the counter value and the increment/decrement buttons. As you press the buttons, the counter value will update and reflect on the UI.
In this article, you learned how to use the BLoC architecture in Flutter. The BLoC architecture provides an effective way to manage application logic and data flow. With code examples and a sample counter application, you’ve learned how to implement the BLoC architecture. You can now apply this knowledge to build more complex applications.
To explore more features and advanced usage of the BLoC architecture, refer to the official documentation of the flutter_bloc package.