Flutter: Value Notifier
Value notifier is a simple class that extends ChangeNotifier and allows you to notify listeners when the value changes.
Example: we will do a simple counter that increments when press a button, our state will be provided by a value notifier.
To start we need 3 files:
- notifier.dart: will be our value notifier
- increment_button.dart: will be our component that will increment the counter
- decrement_button.dart: will be our component that will decrement the counter
//notifier.dart
import 'package:flutter/material.dart';
class _Counter {
ValueNotifier<int> count = ValueNotifier<int>(0);
increment() {
count.value++;
}
decrement() {
count.value--;
}
}
var counter = _Counter();
Here we create a class called _Counter
, that class exposes a ValueNotifier
called count
and two methods increment
and decrement
that will increment and decrement the value of count
.
Now we will create our two buttons.
//increment_button.dart
import 'package:flutter/material.dart';
import 'controller.dart';
class IncrementButton extends StatelessWidget {
const IncrementButton({super.key});
@override
Widget build(BuildContext context) {
return ValueListenableBuilder(
valueListenable: counter.count,
builder: (context, value, child) {
return ElevatedButton(
onPressed: () {
counter.increment();
},
child: SizedBox(
width: 120,
child: Center(
child: Text('Increment: $value'),
),
),
);
},
);
}
}
//decrement_button.dart
import 'package:flutter/material.dart';
import 'controller.dart';
class DecrementButton extends StatelessWidget {
const DecrementButton({super.key});
@override
Widget build(BuildContext context) {
return ValueListenableBuilder(
valueListenable: counter.count,
builder: (context, value, child) {
return ElevatedButton(
onPressed: () {
counter.decrement();
},
child: SizedBox(
width: 120,
child: Center(
child: Text('Decrement: $value'),
),
),
);
},
);
}
}
In these two components we can observe the usage of ValueListenableBuilder
.
That widget will listen to the changes of ValueNotifier
and rebuild the
widget when the value changes.
Now we can use our components in our page.
//page.dart
import 'package:flutter/material.dart';
import 'decrement_component.dart';
import 'increment_component.dart';
class Page extends StatelessWidget {
const Page({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: const Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
IncrementButton(),
SizedBox(height: 20),
DecrementButton(),
],
),
),
);
}
}
The main advantage of using ValueNotifier
is that we can use it in any widget and share the same state.
👉 Check the full code here.