Welcome to the Flutter Project! This project demonstrates various state management techniques and their implementation using different types of builders and state management solutions in Flutter. Below you'll find detailed explanations and usage scenarios for each widget and concept included in this project.
- Getting Started
- Widgets and Scenarios
- Builder
- ValueListenableBuilder
- ValueListenableBuilder with Bloc/Cubit
- ValueListenableBuilder with Services
- BlocBuilder's Universal Memory
- BlocBuilder's Page Memory
- BlocBuilder with Async Function
- BlocBuilder with ValueListenableBuilder
- Cubit and BlocBuilders
- Cubit and ValueListenableBuilders
- BlocBuilder under Build When condition
- CubitBuilder under Build When condition
To get started with this project, clone the repository and install the dependencies:
git clone https://github.com/jinosh05/flutter_builders_eample.git
cd flutter_builders_eample
flutter pub get
Then, run the project:
flutter run
The Builder
widget is a general-purpose widget that builds a widget tree inside the builder function. This is particularly useful when you need a new context with different inherited widgets.
Usage:
Builder(
builder: (BuildContext context) {
return Text('Hello, Builder!');
},
)
The ValueListenableBuilder
is a widget that listens to a ValueListenable
and rebuilds when the value changes.
Usage:
ValueListenableBuilder<int>(
valueListenable: _counter,
builder: (context, value, child) {
return Text('Value: $value');
},
)
Combining ValueListenableBuilder
with Bloc or Cubit allows you to listen to state changes and rebuild the UI accordingly.
Usage:
ValueListenableBuilder<MyState>(
valueListenable: myCubit.stream,
builder: (context, state, child) {
if (state is MyLoadedState) {
return Text('Loaded: ${state.data}');
}
return CircularProgressIndicator();
},
)
Using ValueListenableBuilder
with services is useful for listening to service-based state changes.
Usage:
ValueListenableBuilder<ServiceState>(
valueListenable: myService.stateNotifier,
builder: (context, state, child) {
if (state is ServiceLoadedState) {
return Text('Service Data: ${state.data}');
}
return CircularProgressIndicator();
},
)
BlocBuilder
with universal memory refers to using a single Bloc for managing the state across multiple widgets or screens.
Usage:
BlocBuilder<MyBloc, MyState>(
builder: (context, state) {
if (state is MyLoadedState) {
return Text('Data: ${state.data}');
}
return CircularProgressIndicator();
},
)
BlocBuilder
with page memory is used to retain the state of a particular page or widget, even when navigating away and back to it.
Usage:
BlocProvider(
create: (context) => MyBloc(),
child: MyPage(),
)
// Inside MyPage
BlocBuilder<MyBloc, MyState>(
builder: (context, state) {
if (state is MyLoadedState) {
return Text('Data: ${state.data}');
}
return CircularProgressIndicator();
},
)
Using BlocBuilder
with an async function allows handling asynchronous events and state changes.
Usage:
BlocBuilder<MyBloc, MyState>(
builder: (context, state) {
if (state is MyLoadingState) {
return CircularProgressIndicator();
} else if (state is MyLoadedState) {
return Text('Data: ${state.data}');
}
return Text('Error');
},
)
Combining BlocBuilder
with ValueListenableBuilder
can be useful for listening to both Bloc state changes and other value changes simultaneously.
Usage:
BlocBuilder<MyBloc, MyState>(
builder: (context, state) {
return ValueListenableBuilder<int>(
valueListenable: _counter,
builder: (context, value, child) {
if (state is MyLoadedState) {
return Text('Data: ${state.data}, Counter: $value');
}
return CircularProgressIndicator();
},
);
},
)
Using Cubit
and BlocBuilder
together provides a more lightweight alternative to Bloc while still managing state effectively.
Usage:
CubitBuilder<MyCubit, MyState>(
builder: (context, state) {
if (state is MyLoadedState) {
return Text('Data: ${state.data}');
}
return CircularProgressIndicator();
},
)
Combining Cubit
with ValueListenableBuilder
allows listening to both Cubit state and other value changes.
Usage:
CubitBuilder<MyCubit, MyState>(
builder: (context, state) {
return ValueListenableBuilder<int>(
valueListenable: _counter,
builder: (context, value, child) {
if (state is MyLoadedState) {
return Text('Data: ${state.data}, Counter: $value');
}
return CircularProgressIndicator();
},
);
},
)
BlocBuilder
with a buildWhen
condition allows you to conditionally rebuild your widget based on specific state changes.
Usage:
BlocBuilder<MyBloc, MyState>(
buildWhen: (previous, current) {
return current is MySpecificState; // Only rebuild if the state is MySpecificState
},
builder: (context, state) {
if (state is MySpecificState) {
return Text('Specific State Data: ${state.data}');
}
return CircularProgressIndicator();
},
)
CubitBuilder
with a buildWhen
condition allows you to conditionally rebuild your widget based on specific state changes.
Usage:
CubitBuilder<MyCubit, MyState>(
buildWhen: (previous, current) {
return current is MySpecificState; // Only rebuild if the state is MySpecificState
},
builder: (context, state) {
if (state is MySpecificState) {
return Text('Specific State Data: ${state.data}');
}
return CircularProgressIndicator();
},
)
This project demonstrates various advanced state management techniques in Flutter using different combinations of Builder
, ValueListenableBuilder
, BlocBuilder
, and Cubit
. Feel free to explore the code and adapt these patterns to your own Flutter projects!
If you have any questions or suggestions, please open an issue or submit a pull request.
Happy coding!
Remember to replace placeholders like MyBloc
, MyState
, MyCubit
, myService
, myCubit
, _counter
, etc., with actual implementations relevant to your project.