Flutter Bloc Architecture
Flutter Bloc Architecture
At its most basic, state is data that is read synchronously and can change over time. For example, a Text
widget value is updated to show the latest game score, and the state for the Text widget is the value.
State management is the way to share data (state) between pages and widgets.
This is to share the state between different pages. For example the authentication state
manager monitors the logged-in user and when the user logs out, it takes the appropriate action
to redirect to the login page.
Local-state management
It confined to a single page or a single widget. For example, the page displays a selected item,
and the purchase button needs to be enabled only if the item is in stock. The button widget
needs to access the state of the in-stock value.
There are many difference techniques for handling state management. One of the state
management technique is the setState() method.
Implementing an Abstract class
One of the main benefits of using an abstract class is to separate the interface methods (called from the
UI) from the actual code logic. In other words, you declare the methods without any implementation
(code). Other benefits is that the abstract class cannot be directly instantiated, meaning an object
cannot be created from it unless you define a factory constructor. Abstract classes help you to program
to interfaces, not the implementation. Concreate classes implement the methods of the abstract class.
abstract class Authentication {
Future<void> sendEmailVerification();
Future<bool> isEmailVerified();
}
Why use an abstract class instead of declaring a class with variables and methods? Of course, you can
use the class without creating an abstract class for the interface since the class already declares them by
default. But once of the benefits of using abstract class is to impose implementation and design
constraints.
Bloc Architecture
When you use flutter bloc you are going to create events to trigger the interactions with the app and
then the bloc in charge is going to emit the requested data with a state, in a real example it will be like
that:
BlocProvider/MultiBlocProvider
BlocProvider is in charge of providing a bloc to its children. Is the way of ‘initializing’ the bloc before
using it.
BlocProvider(
create: (BuildContext context)=> GamesBloc(),
child: HomePage(),
);
If you need to provide more than one bloc you can use the MultiBlocProvider to get different providers
MultiBlocProvider(
providers: [
BlocProvider<GamesBloc>(
Create: (BuildContext context)=>GamesBloc(),
),
BlocProvider<CategoryBloc>(
create: (BuildConext context)=>CategoryBloc(),
),
],
child: HomePage(),
)
RepositoryProvider/MultiRepositoryProvider
RepositoryProvider is used to provide a repository to its children. Normally you are going to use it when
you need to create an instance of your repository class and then with the BlocProvider, you are going to
access that repository with help of context.read<YourRepository>();
RepositoryProvider(
create: (context)=> gamesRepository(),
child: HomePage(),
);
MultiRepositoryProvider(
providers: [
RepositoryProvider<GamesRepository>(
create: (context)=> GamesRepository(),
),
RepositoryProvider<AuthRepository>(
create: (context)=>AuthRepository(),
),
],
child: HomePage(),
)
BlocListener
With this widget, you are going to be able to ‘listen’ to different states that would be emitted from your
bloc and then react to them, for example, to show a snackbar, dialog, or navigate tot another page.. This
widget does not rebuild the view, is only listening.
BlocListener<GamesBloc, GamesState>(
Listener: (context,state){
If(state.isSuccess){
// for example: show snackbar
}
},
child: HomeLayout(),
)
BlocBuilder
With this, you are going to be able to rebuild your widget depending on their state.
BlocBuilder<GamesBloc, GamesState>(
builder: (context,state) {
if(state.isSucces){
return GamesWidgetSuccess();
}else if (state.isError){
Return ErrorWidget();
}else {
Return InitialWidget();
}
}
)
BlocConsumer
This widget is super useful when you need to control the states of your bloc to rebuild the widget and
also for navigate or show a dialog, etc. This widget has the listener and the builder function so that you
can use it together.
BlocConsumer<GamesBloc, GamesState>(
listener: (context,state){
if(state.isError){
context.read<GamesBloc>().add(GetGames());
}
},
builder: (context,state){
if(state.isLoading){
return Loader();
}
else if(state.isSuccess){
return GamesSuccessWidget();
}
else {
return OtherWidget();
}
}
);
BlocSelector
This widget allows developers to filter updates by selecting a new value based on the current bloc state.
BlocSelector<GamesBloc,GamesState,bool>(
selector: (state)=>state.isSelected ? true : false,
builder: (context,state){
return Container(
width: 50.0,
height:50,
color: state ? Colors.blue: Colors.orange
)
},
)
BlocConsumer
states request
UI bloc THE THE DATA
events response REPOSITORIES PROVIDERS
THE MODELS
BLOC CUBITS