Table of contents
1.
Introduction
2.
What Is Flutter Bloc?
3.
How does it work?
4.
Bloc Widgets
5.
Understanding Concept of BLoC: Events & States
6.
Example
6.1.
Code Implementation
6.2.
Output and Explanation
7.
Advantages of BLoC Design Pattern
8.
Disadvantages of BLoC Design Pattern
9.
Frequently Asked Questions:
9.1.
What is Bloc pattern Flutter?
9.2.
What is the purpose of BLoC in Flutter?
9.3.
Which state management is best in Flutter?
9.4.
Is Bloc better than GetX?
10.
Conclusion
Last Updated: Mar 27, 2024
Easy

Flutter Bloc

Author Sanchit Kumar
0 upvote

Introduction

Flutter Bloc is a state management library for the Flutter framework that helps developers organise and manage application states reactively and efficiently. It follows the Business Logic Component (BLoC) pattern, separating business logic from the UI layer.

Flutter Bloc

With Flutter Bloc, you can create maintainable and testable Flutter applications that are scalable and easy to reason about. The flutter state management feature allows handling all possible application states efficiently.

What Is Flutter Bloc?

Flutter Bloc is a state management pattern and library for Flutter, a popular open-source UI software development toolkit created by Google. State management is a crucial aspect of building complex applications, and Flutter Bloc provides a structured way to manage and update the state of a Flutter application.

Bloc stands for Business Logic Component, and the Flutter Bloc library helps in organizing and managing the flow of data and events in your application. It follows the reactive programming paradigm, where the UI components react to changes in the application state.

Below is the list of packages included in the Bloc:

Bloc Core Bloc Library
Flutter_bloc                                                                                          flutter_bloc is an extension of the core Bloc library, specifically designed for Flutter applications. It provides additional utilities and features that make it easier to integrate Bloc pattern into Flutter widgets.
Angular_bloc angular_bloc is an extension of the core Bloc library for AngularDart, which is the Dart version of the Angular framework for building web applications. It brings the Bloc pattern to AngularDart applications, providing a similar structure for managing state and events as in Flutter.
Hydrated_bloc hydrated_bloc is a library that extends the Flutter Bloc library, providing additional functionality for state persistence. It allows you to persist and hydrate (restore) the state of your Blocs across app restarts or other state changes, improving the user experience by preserving the application's state.
Replay_bloc An extension to the bloc state management library which adds support for undo and redo.

How does it work?

The core idea of Flutter Bloc is to separate the business logic (Bloc) from the UI, making the code more modular, testable, and maintainable. Let us look at the how Flutter Bloc works:

  1. Events: User interactions or system events trigger events in the application. Events are dispatched to the Bloc, representing things like button clicks, data loading requests, or any action that should cause a change in the application state.
     
  2. Bloc: The Bloc is responsible for managing the application state. It listens to incoming events and processes them, updating the state accordingly. The state changes are then broadcasted to the UI components.
     
  3. States: States represent the different conditions or snapshots of the application. The UI components rebuild based on the current state, reflecting changes to the user.
     
  4. UI Integration: Flutter provides specific widgets to integrate with Blocs, such as BlocBuilder, BlocProvider, and BlocListener. BlocBuilder is a widget that rebuilds itself whenever the state of the Bloc changes. It helps in updating the UI based on the current state. BlocProvider is used to provide the Bloc instance to the widget tree so that child widgets can access it.
     
  5. Streams: Flutter Bloc relies on Dart's Streams for handling asynchronous operations. The Bloc listens to an input stream for events, processes them, and emits new states to an output stream. Widgets subscribe to the output stream to receive updates and rebuild when the state changes.

Bloc Widgets

Bloc Widgets are not a specific category of widgets but rather widgets provided by the Flutter Bloc library to facilitate integration with the Bloc pattern. Here are a few important ones:

  • BlocBuilder: A widget that rebuilds itself based on the latest state emitted by a Bloc. It takes a Bloc and a builder function, which defines how the widget should be rebuilt based on the current state.
     
  • BlocProvider: A widget that provides a Bloc to its descendants in the widget tree. It is used at the root of a widget tree to make a Bloc accessible to all the widgets below it.
     
  • BlocListener: A widget that listens to state changes in a Bloc and executes a callback in response to those changes. It's useful for performing side effects based on Bloc state transitions.
     

These widgets help in seamlessly integrating the Bloc pattern into Flutter applications, making it easier to manage state and update the UI in a reactive and predictable manner.

Understanding Concept of BLoC: Events & States

  • Events: Events are inputs of an application like button_press to load images, text inputs, or any other user input that an application may receive.
  • States: They are simply the application's state, which can alter in response to the event received.


Bloc manages these events and states, i.e., transforming a stream of Events into a stream of States as output. 

Creating An Event

@immutable
abstract class AppBlocEvent {
	const AppBlocEvent();
}

@immutable
class ChangeTextEvent extends AppBlocEvent {
	const ChangeTextEvent();
}


Creating A State

@immutable
class AppState extends Equatable {
	final int index;
	final String text;

	const AppState.empty()
		: index = 0,
			text = 'Initial Text';

	const AppState({
		required this.index,
		required this.text,
	});

	@Override
	List<Object> get props => [index, text];
}

Example

In this example, we will use Flutter BLoC to create a simple counting app. The CounterBloc class will manage the logic for incrementing and decrementing the counter. It will extend Bloc<CounterEvent, CounterState>.

The primary app screen that will use BlocBuilder will display the current count in the CounterPage widget. Additionally, it will contain two floating action buttons that, when clicked, will trigger CounterEvent.increment and CounterEvent.decrement events.

The CounterBloc will evaluate the dispatched events in the mapEventToState method and emit the updated state (the updated count). The BlocBuilder will monitor state changes and will reconstruct the UI as necessary.

Code Implementation

Follow the steps below to implement the counter application.


Step 1: Create a Flutter project in your code editor.
 

Step 2: Add flutter_block dependency in pubspec.yaml.

dependencies:
	flutter:
		sdk: flutter
	flutter_bloc: ^7.0.0
	bloc: ^7.0.0


Step 3: Create a file for the Bloc class. Let's name it couter_bloc.dart.

import 'package:bloc/bloc.dart';

// Define the events
enum CounterEvent { increment, decrement }

// Define the state
class CounterState {
	final int count;
	CounterState(this.count);
}

// Define the BLoC class
class CounterBloc extends Bloc<CounterEvent, CounterState> {
	CounterBloc() : super(CounterState(0));

	@Override
	Stream<CounterState> mapEventToState(CounterEvent event) async* {
		switch (event) {
			case CounterEvent.increment:
				yield CounterState(state.count + 1);
				break;
			case CounterEvent.decrement:
				yield CounterState(state.count - 1);
				break;
		}
	}
}


Step 4: In the main.dart file, write the following code:

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'counter_bloc.dart';

void main() {
	runApp(MyApp());
}

class MyApp extends StatelessWidget {
	@Override
	Widget build(BuildContext context) {
		return MaterialApp(
			home: BlocProvider(
				create: (context) => CounterBloc(),
				child: CounterPage(),
			),
		);
	}
}

class CounterPage extends StatelessWidget {
	@Override
	Widget build(BuildContext context) {
		// Access the CounterBloc instance from the context
		final CounterBloc counterBloc = BlocProvider.of<CounterBloc>(context);

		return Scaffold(
			appBar: AppBar(title: Text('Counter App')),
			body: Center(
				child: BlocBuilder<CounterBloc, CounterState>(
					builder: (context, state) {
						return Text(
							'Count: ${state.count}',
							style: TextStyle(fontSize: 24),
						);
					},
				),
			),
			floatingActionButton: Column(
				mainAxisAlignment: MainAxisAlignment.end,
				crossAxisAlignment: CrossAxisAlignment.end,
				children: [
					FloatingActionButton(
						onPressed: () {
							// Dispatch the increment event to the CounterBloc
							counterBloc.add(CounterEvent.increment);
						},
						child: Icon(Icons.add),
					),
					SizedBox(height: 10),
					FloatingActionButton(
						onPressed: () {
							// Dispatch the decrement event to the CounterBloc
							counterBloc.add(CounterEvent.decrement);
						},
						child: Icon(Icons.remove),
					),
				],
			),
		);
	}
}

Output and Explanation

When you run the app, it will open a screen with the title "Counter App" on the top of the App bar. The centre of the screen will show the current count, which initially starts at 0. The count will increase or decrease on clicking the "+" FAB or "-" FAB, respectively. The BlocBuilder widget will automatically update the UI to reflect the changes in the count as the state is updated in the CounterBloc.

output

 

So with this app, we learnt the basic implementation of the BLoC pattern using the Flutter BLoC library.

Before initiating the flutter bloc tutorial, let's analyse some of the pros and cons of the bloc design pattern.

Recommended Topic: Clean Architecture

Advantages of BLoC Design Pattern

  • It provides good documentation about different scenarios.
     
  • It separates the business logic from the code, thus making the code understandable.
     
  • Using BLoC makes the outcome more testable.
     
  • It is easy to keep track of different states that occur during product development.

Disadvantages of BLoC Design Pattern

  • Implementing Flutter Bloc requires writing boilerplate code for defining events, states, and blocs, which might increase code verbosity.
     
  • Debugging can be more challenging with Flutter Bloc, as the flow of events and states can be intricate.
     
  • Flutter Bloc might introduce unnecessary complexity for small or simple applications compared to more straightforward state management solutions like setState.

Frequently Asked Questions:

What is Bloc pattern Flutter?

Bloc pattern in Flutter is a state management approach, separating business logic from UI, improving organization, and making apps more maintainable.

What is the purpose of BLoC in Flutter?

The purpose of BLoC in Flutter is to manage and separate business logic, events, and states, enhancing code modularity and testability for a reactive UI.

Which state management is best in Flutter?

There's no one-size-fits-all. Bloc is popular for complex apps, while Provider and Riverpod are simpler. Choose based on project needs.

Is Bloc better than GetX?

"Better" depends on context. Bloc is widely used for its structure, while GetX is praised for simplicity and performance. Choose based on project requirements and developer preferences.

Conclusion

This article taught us about Flutter BLoC, a powerful state management library that enables the separation of concerns and organised application state handling. We delved into the advantages and disadvantages of the BLoC design pattern, understanding the role of events and states in managing application states reactively. We implemented a counting app through a step-by-step example and learnt the basic implementation of the BLoC pattern using the Flutter BLoC library.

To learn more things related to Flutter, you can refer to the following articles.

You may refer to our Guided Path on Code Studios for enhancing your skill set on DSACompetitive ProgrammingSystem Design, etc. Check out essential interview questions, practice our available mock tests, look at the interview bundle for interview preparations, and so much more!

Happy Learning, Ninja!

Live masterclass