State Management using ChangeNotifier and AnimatedBuilder for Dashboard App
Dashboard using ChangeNotifier
and AnimatedBuilder
.
State Management by using built-in Flutter classes. No Packages.
What is State Management?
State Management is not a simple topic. How do you know if you need it? Usually, once you start developing an application you will run into this issue, how do I manage the state of data, how do I access data from different parts of the app?
We have ephemeral and app state that we can use. An ephemeral state is a local state that lives in a single widget, like a single page of the application. App state can be global, app-wide state that is shared in different parts of the app.
There is no definite way to handle state management, this is something that you need to decide depending on your needs and likes. On a simple application, the default setState() can manage to refresh the page, but what if the page has many widgets/parts that need to redraw, you do not want to refresh the entire page because it will cause that janky animation. In those cases you only want to redraw each widget as needed, therefore increasing performance.
Video Tutorial
Video Tutorial: YouTube Video
Source Code: GitHub
What is covered
In this project, you are going to take a look at:
- How to use
ChangeNotifier
andAnimatedBuilder
to selectively rebuild individual widgets for performance - State Management with build-in classes, no packages
The Problem:
- Dashboard app needs to chart espresso, coffee, latte and total consumption
- Drawing each section bar, the chart needs to refresh independently for performance
The Solution:
- Use the
ChangeNotifier
andAnimatedBuilder
to allow to selectively rebuild individual widgets for performance
ValueNotifier and ValueListenableBuilder
The ChangeNotifier
and AnimatedBuilder
allow to selectively rebuild individual widgets for performance
- Create a class that extends
ChangeNotifier
- Add fields to contain data
- Add methods to modify data and call the
notifyListeners()
method - Add the
AnimatedBuilder
widget in the widget tree to rebuild widgets selectively if the data changed
class Section {
int espresso = 0;
int coffee = 0;
int latte = 0;Section(
{required this.espresso,
required this.coffee,
required this.latte});
}class TotalCoffeeChangeNotifier extends ChangeNotifier {
int totalCoffee = 0;void totalNumberOfCoffee({required int espresso, required int coffee, required int latte}) {
totalCoffee = espresso + coffee + latte;
notifyListeners();
}
}class CoffeeChangeNotifier extends ChangeNotifier {
late Section section;void addNumberOfCoffee({required int espresso, required int coffee, required int latte}) {
section.espresso += espresso;
section.coffee += coffee;
section.latte += latte;
notifyListeners();
}
}// Child Widget
AnimatedBuilder(
animation: totalCoffeeChangeNotifier,
builder: (BuildContext context, Widget? snapshot) {
debugPrint('Total: ${totalCoffeeChangeNotifier.totalCoffee}');
return MoodVerticalBarWidget(
icon: Icons.local_cafe_outlined,
numberToPlot: totalCoffeeChangeNotifier.totalCoffee,
numberToPlotMax: numberToPlotMax,
title: 'Total',
);
}
),
How it Works
• ChangeNotifier
and AnimatedBuilder
– The ChangeNotifier
and AnimatedBuilder
allow to selectively rebuild individual widgets for performance. Use fields to contain data defining them in the ChangeNotifier
. Use methods to modify data and call the notifyListeners()
method. Use the AnimatedBuilder
widget in the widget tree to rebuild widgets selectively if the data changed.