Flutter is a powerful framework for developing native apps for iOS, Android, and the web. However, as apps become more complex, the managing state can become difficult. This is where the BLoC (Business Logic Component) package comes in. BLoC is a design pattern for managing state in Flutter apps, and the BLoC package provides tools for implementing this pattern.
The BLoC pattern separates business logic from presentation, making it easier to test and maintain code. In this pattern, the UI communicates with a BLoC, which handles all the business logic and state management. The BLoC then emits streams of data, which the UI can listen to and update the UI accordingly.
The BLoC package provides three main components for implementing the BLoC pattern:
- The
Bloc
class: This is the main class for creating a BLoC. It handles all the business logic and state management. - The
BlocProvider
widget: This widget provides a BLoC to its children. It creates a new instance of a BLoC and makes it available to all the widgets that are its descendants. - The
BlocBuilder
widget: This widget listens to a stream of data emitted by a BLoC and rebuilds the UI when the data changes.
Let’s take a look at an example of implementing the BLoC pattern using the BLoC package:
- Add the BLoC package to your project’s dependencies in the
pubspec.yaml
file:
dependencies:
flutter:
sdk: flutter
bloc: ^7.0.0
- Create a class that extends
Bloc
. This class will hold the state of the app and handle all the business logic. For example:
import 'package:bloc/bloc.dart';
class CounterBloc extends Bloc<int, int> {
CounterBloc() : super(0);
@override
Stream<int> mapEventToState(int event) async* {
yield state + event;
}
}
In this example, the CounterBloc
class holds the state of the app, which is a simple integer counter. The mapEventToState
method updates the counter and emits a new stream of data whenever the counter changes.
- Wrap your widgets in a
BlocProvider
widget to provide the BLoC to the widgets that need it. For example:
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
class MyHomePage extends StatelessWidget {
const MyHomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return BlocProvider(
create: (_) => CounterBloc(),
child: Scaffold(
appBar: AppBar(
title: Text('BLoC Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the button this many times:',
),
BlocBuilder<CounterBloc, int>(
builder: (context, count) {
return Text(
'$count',
style: Theme.of(context).textTheme.headline4,
);
},
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
context.read<CounterBloc>().add(1);
},
tooltip: 'Increment',
child: Icon(Icons.add),
),
),
);
}
}
In this example, the MyHomePage
widget is wrapped in a BlocProvider
widget that creates an instance of the CounterBloc
class. The BlocBuilder
widget listens to the stream of data emitted by the CounterBloc
and rebuilds the UI whenever the counter changes. The floatingActionButton
increments the counter by calling the add
method on the CounterBloc
instance provided by the BuildContext
.
Run the app and see the BLoC pattern in action! You should be able to increment the counter by tapping the floating action button.
The BLoC pattern and the BLoC package can make it easier to manage state in your Flutter app. By separating business logic from presentation and using streams of data to communicate between the two, you can create more maintainable and testable code.
Stay connected for more!
The more you share… more you learn… follow for more….