Commit 9a83659d authored by Adam Barth's avatar Adam Barth Committed by GitHub

Add ValueNotifier (#8463)

It's common to have a ChangeNotifier that wraps a single value. This class
makes that easy by providing a generic implementation.
parent 96ba7f76
...@@ -37,6 +37,10 @@ abstract class Listenable { ...@@ -37,6 +37,10 @@ abstract class Listenable {
/// [ChangeNotifier] is optimised for small numbers (one or two) of listeners. /// [ChangeNotifier] is optimised for small numbers (one or two) of listeners.
/// It is O(N) for adding and removing listeners and O(N²) for dispatching /// It is O(N) for adding and removing listeners and O(N²) for dispatching
/// notifications (where N is the number of listeners). /// notifications (where N is the number of listeners).
///
/// See also:
///
/// * [ValueNotifier], which is a [ChangeNotifier] that wraps a single value.
class ChangeNotifier extends Listenable { class ChangeNotifier extends Listenable {
ObserverList<VoidCallback> _listeners = new ObserverList<VoidCallback>(); ObserverList<VoidCallback> _listeners = new ObserverList<VoidCallback>();
...@@ -155,3 +159,23 @@ class _MergingListenable extends ChangeNotifier { ...@@ -155,3 +159,23 @@ class _MergingListenable extends ChangeNotifier {
super.dispose(); super.dispose();
} }
} }
/// A [ChangeNotifier] that holds a single value.
///
/// When [value] is replaced, this class notifies its listeners.
class ValueNotifier<T> extends ChangeNotifier {
/// Creates a [ChangeNotifier] that wraps this value.
ValueNotifier(this._value);
/// The current value stored in this notifier.
///
/// When the value is replaced, this class notifies its listeners.
T get value => _value;
T _value;
set value(T newValue) {
if (_value == newValue)
return;
_value = newValue;
notifyListeners();
}
}
...@@ -190,4 +190,20 @@ void main() { ...@@ -190,4 +190,20 @@ void main() {
expect(() { source.dispose(); }, throwsFlutterError); expect(() { source.dispose(); }, throwsFlutterError);
expect(() { source.notify(); }, throwsFlutterError); expect(() { source.notify(); }, throwsFlutterError);
}); });
test('Value notifier', () {
final ValueNotifier<double> notifier = new ValueNotifier<double>(2.0);
final List<double> log = <double>[];
final VoidCallback listener = () { log.add(notifier.value); };
notifier.addListener(listener);
notifier.value = 3.0;
expect(log, equals(<double>[ 3.0 ]));
log.clear();
notifier.value = 3.0;
expect(log, isEmpty);
});
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment