Flutter: ValueNotifier and ValueListenableBuilder

Avnish Nishad
3 min readOct 15, 2021

--

Flutter is a powerful framework and it’s continuously growing and apps on the stores are made using the flutter framework too. We all are good programmers but what makes us pro is code that is easy to test, maintain, and reusable.

Today, we are going to use ValueNotifiers to rebuild a widget without using setState.

Create ValueNotifier

Change ValueNotifier values

Use Them using ValueListenableBuilder

Nested ValueListenableBuilder

Disposal of ValueListeners

Use of Optional child parameter (Must read)

ValueNotifier is a special type of class that extends Changenotifier, which can hold a single value and notifies the widgets which are listening to it whenever its holding value gets change.

Note: ValueNotifier is useful and performance efficient because it rebuilds only the Widgets that are listening to it using ValueListenableBuilder.

  1. Create Value Notifier : ValueNotifier is easy to create and for that, we will create a new file value_notifiers.dart that will hold all the ValueNotifiers in one file.

ValueNotifiers can hold data of type int, String, double, boolean and even you can use your own Datatype (using class).

import 'package:flutter/material.dart';ValueNotifier<int> buttonClickedTimes =ValueNotifier(0);

APP SCENARIO: We are making an app that will count the number of times a button get clicked and to understand how ValueNotifier works, we are going to make a separate stateless widget class for the button and to show the counter we are making a Stateless widget that also acts as parent widget for button widget.

2. Change ValueNotifier values: In button widget, we are going to increment the ValueNotifier value.

// don't forget to import value_notifiers.dart otherwise it will give error.GestureDetector(
onTap:()=>buttonClickedTimes.value= buttonClickedTimes.value+1,
child: Text("Button",style:Theme.of(context).textTheme.button)
);

3. ValueListenableBuilder: ValueListenableBuilder is the widget that is used to access the ValueNotifier and rebuild the part of UI which depends on ValueNotifier value.

In the parent widget, we are going to surround the Text widget by ValueListenableBuilder.

ValueListenableBuilder(
valueListenable: buttonClickedTimes,
builder: (BuildContext context, int counterValue,Widget child){
return Text("Counter:$counterValue");
}
)

builder:(@required BuildContext context, @required int counterValue, Widget child) helps to rebuild the UI whenever the ValueNotifier value gets change.

4. Nested ValueListenableBuilder: If a widget depends on more than one ValueNotifier then we use nested ValueListenableBuilder.

ValueListenableBuilder(
valueListenable: buttonClickedTimes,
builder: (BuildContext context, int counterValue,Widget child)
return ValueListenableBuilder(
valueListenable: textColor,
builder: (context, textColorValue,child)
Text("Counter:$counterValue", style: TextStyle(color:textColorValue));
))

5. Disposal of ValueNotifiers: It's always a good practice to dispose all the ValueNotifiers once they are no longer in use which can save the app from memory loss.

@override
void dispose() {
buttonClickedTimes.dispose();
textColor.dispose();
super.dispose();
}

6. Optional Parameter Child:

The child parameter is optional but is useful in order to make use of ValueNotifier and ValueListenableBuilder even more performance efficient.

ValueListenableBuilder(
valueListenable: ColorNotifier,
builder: (BuildContext context, int colorValue, Widget child){
return Container(
height:100,
width:100,
color:colorValue,
child:child);
},
child:Text("button",textAlign:TextAlign.center),
)

In the above code, Container is using colorNotifier to change its color, and Text widget having the same value no matters what the colorNotifier value is, but because it is a child of Container it will get rebuild when Container get rebuilds. And to counter this issue Optional child parameter comes to rescue us.

Stay Tuned for these types of blogs and If you find this tutorial useful let us know in the comment section.

--

--