Managing the User-Interface(UI) of an application without external flutter plugins can be quite satisfying especially when building simple applications. For state management, Flutter uses the setState function, which is often called in a Stateful widget. In most cases, the use of setState is appropriate and functional, but if not properly used could pose certain issues.
Rebuilds the entire widget, which is a time-consuming and expensive process.
Limited flexibility between frontend and backend.
For this reason, we shall be taking a proper look at ValueNotifier and how it solves all the issues listed above. ValueNotifier is a good choice for building reactive applications with enhanced performance. It comes in handy when you want to update a UI due to a change in a value, as it reduces the number of times the entire widget is rebuilt.
It is requisite to call setState in a stateful widget, but with ValueNotifier, the UI can dynamically be updated, even inside a stateless widget. In this article, we shall take a deep dive into
ValueListenableBuilder and how to use them to manage and update UIs effectively. We shall also go through building a CV App using
What is ValueNotifier?
ValueNotifier is a subclass of ChangeNotifier that allows you to store a single value and notifies its listeners when the value changes. It is a powerful, simple, and portable solution for creating reactive data sources in Flutter. For example, you may use a ValueNotifier to monitor changes to a TextField’s value, so that the value can be updated and reflected in other UI elements.
The value could be of any type, it could be
Bool or even a custom DataType using
ValueNotifier is native to Flutter and by default, it has a widget that it uses to listen to the ValueNotifier value, this widget is called
ValueListenableBuilder. The AnimatedBuilder can also be used to listen to, depending on the requirements and use case of a project.
The ValueNotifier object is consumed by the ValueListenableBuilder. It listens to the ValueNotifier value using the
valueListenable property and rebuilds just the widget state that is passed to it. The ValueListenableBuilder has 3 properties, as follows:
a. valueListenable: It takes on the value to be listened to. It is in fact, an instance of ValueNotifier.
b. builder: the builder function rebuilds the widget depending on the valueListenable value.
c. child: this widget tree does not get rebuilt, even when there are changes to the value. The child parameter is optional but useful, as it aids performance efficiency.
Advantages of ValueNotifier:
It supports Element-specific reactivity.
It limits the number of times a widget is rebuilt.
It is less resource-intensive than setState for simple use cases and does not require the development of complex stream controllers.
Disadvantage of ValueNotifier:
- A major shortcoming of the ValueNotifier class is that listeners will not be notified when a mutable state within the value itself changes because this class only alerts listeners when the value’s identity changes. For instance, a
ValueNotifier<List<int>>will not notify its listeners when the contents of the List have changed. Therefore, this class is best used with only immutable data.
To properly follow through with this guide, you should have basic knowledge of Dart and Flutter. You must have the Flutter and Dart Software development kit installed in your system. Lastly, get your code editor ready.
About the CV Application:
For this application, we will create two screens, one to display the user’s CV details
CvPage and the other to edit the CV details
EditPage. We would also create a model class that holds ValueNotifier values, and then instantiate this class in the
EditPage. ValueListenableBuilder will be used to listen to changes in the ValueNotifier and update the CvPage accordingly. The CvPage shall display the following details: full name, email, GitHub handle, LinkedIn handle and a brief bio.
Creating a CV Application:
Let’s start by creating a new flutter project, you can give it any name. I gave mine
cvApp. Afterwards, go to your lib folder and create three dart files; CvPage, EditPage and model. In
main.dart, home: will be set to
To keep things orderly and simple we’ll create a class called
CvDetails in the
model.dart file. This class holds personal information as ValueNotifier<String>. Thereafter, set initial parameters in the class Constructor, so that they can be populated with values, to enable the user’s CV particulars to appear(prefilled) on the CV screen, upon launching the app.
Next, go to your
main.dart file, and initialize
cvDetails in the
MyApp class with default values that will appear on the CV screen upon app launch.
Creating the CV Screen:
Create a stateless widget called
CvPage, instantiate the
CvDetails class and make it required. The instantiation is to enable us to call data from the
CvDetails class into this page.
Next, we design the layout of the
CvPage and use the
ValuableListenableBuilder to listen to the values from our
ValueNotifiers. Below the page, we will add an ‘Edit Button’ that navigates you to the
EditPage when you click it. Remember, that initial information will be displayed on the CV screen.
You'll observe that the
ValueListenableBuilder is returning a Text widget, the
valueListenable property listens to the
valueNotifier value and rebuilds only the Text widget when a change in value occurs. With this our CvPage is ready.
View source code on GitHub.
Creating the Edit Screen:
To create the Edit Screen, create a stateful widget called
EditPage and instantiate the
CvDetails class, just like we did in
CvPage. Afterward, create textControllers for each value field. These
TextControllers will take user input that will be listened to and updated by the
We will also override a
void initState() function that displays the default values on the
CvPage, in the
EditPage TextFields, so that editing by the user can be achieved easily.
Next, we shall create a layout for the
EditPage, our layout will display TextFields.
View source code on Github:
There will also be a ‘Save button’ that immediately pops back to the CvPage, reflecting the changes made in real time.
Disposal of ValueNotifiers:
Do not forget that, it is best practice to dispose of all ValueNotifiers when they are no longer in use, to prevent memory leaks in your application.
If you followed through to this point, your application should look like this, by the time you are done.
As you have seen, using ValueNotifier and ValueListenableBuilder in your applications is pretty straightforward, easy and time-saving. Now that you have built a simple CV App, you can further explore different ways to improve the features and performance of your app using the ValueListenableBuilder as it can be applied to any widget. See you in my next one. Ciao.