ValueNotifier and ValueListenableBuilder in Flutter

Abhishek Dixit
GYTWorkz
Published in
3 min readJan 16, 2023

In 2023, Flutter will be one of the most popular cross-platform frameworks for developing mobile apps. Flutter is Google’s UI toolkit for creating beautiful, natively compiled mobile, web, and desktop applications from a single codebase. In this post, we will take a deep dive into ValueNotifier and its related topics.

To understand the need for a ValueNotifier, we must first understand Flutter’s underlying architecture. We need to understand how the widgets are rebuilt when we call them.

Reference

What is ValueNotifier & ValueListenableBuilder in Flutter?

A ValueNotifier is a simple class that allows you to expose a value and provide notifications when the value changes. It is often used in Flutter to hold and manage state.

The ValueNotifier class extends the ChangeNotifier class, which provides the ability to notify listeners when the value changes. To create a ValueNotifier, you need to pass the initial value to the constructor. You can then expose the value using the value property and update it using the value setter.

Here is an example of how you might use a ValueNotifier in a Flutter app:

import 'package:flutter/material.dart';

void main() {
runApp(MyApp());
}

class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
final counter = ValueNotifier<int>(0);

void increment() {
counter.value++;
}

@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Counter: ${counter.value}'),
RaisedButton(
onPressed: increment,
child: Text('Increment'),
),
],
),
),
),
);
}
}

In this example, the counter variable is a ValueNotifier that holds an integer value. The increment method increments the value of the counter and the Text widget displays the current value.

The ValueNotifier class is often used in conjunction with the ValueListenableBuilder widget, which allows you to rebuild a widget tree whenever the value of the ValueNotifier changes. This can be useful for optimizing the performance of your app by avoiding unnecessary rebuilds.

Here is an example of how you might use the ValueListenableBuilder widget:

import 'package:flutter/material.dart';

void main() {
runApp(MyApp());
}

class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
final counter = ValueNotifier<int>(0);

void increment() {
counter.value++;
}

@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: ValueListenableBuilder(
valueListenable: counter,
builder: (context, value, child) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Counter: $value'),
RaisedButton(
onPressed: increment,
child: Text('Increment'),
),
],
);
},
),
),
),
);
}
}

In this example, the ValueListenableBuilder widget is wrapped around the Column widget that displays the counter value and the button. The valueListenable property of the ValueListenableBuilder is set to the counter ValueNotifier, and the builder function is called whenever the value of the counter changes. This allows the Column widget to be rebuilt only when the value of the counter changes, rather than being rebuilt on every frame.

Using a ValueNotifier and a ValueListenableBuilder can be a useful way to manage and optimize the state of your Flutter app. However, it is important to note that ValueNotifier does not automatically trigger a rebuild of its dependents when the value changes. Instead, you must manually call the notifyListeners method to trigger a rebuild.

In addition to ValueNotifier, Flutter also provides the InheritedWidget and Provider classes, which can be used to manage and expose state in a Flutter app. It is important to choose the right tool for the job based on the requirements of your app.

click

Don’t forget to connect with me on:

--

--