数据传递/状态管理 一ValueNotifier
关于 ValueNotifier
的注释
/// A [ChangeNotifier] that holds a single value.
///
/// When [value] is replaced with something that is not equal to the old
/// value as evaluated by the equality operator ==, this class notifies its
/// listeners.
翻译过来大致意思是说 ValueNotifier
包含一个 value
值,当值改变的时候,会通知它的监听者,先通过示例来看如何使用。
-
示例很简单,点击按钮修改值,文本显示的值同步更新。
代码比较简单,创建一个ValueNotifier
对象,在 initState
和 dispose
分别添加和注销数据变化的监听,按钮点击修改ValueNotifier
里面的值会回调监听update
,完成界面的刷新重建。
class ValueNotifierDemo extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return new _ValueNotifierDemoState();
}
}
class _ValueNotifierDemoState extends State<ValueNotifierDemo> {
ValueNotifier<int> _valueNotifier = new ValueNotifier(0);
@override
void initState() {
super.initState();
///添加数据的变化监听
_valueNotifier.addListener(update);
}
@override
void dispose() {
super.dispose();
///组件销毁的时候注销监听
_valueNotifier.removeListener(update);
}
void update() {
print("数据变化监听回调");
///刷新重建界面
setState(() {});
}
@override
Widget build(BuildContext context) {
return new MaterialApp(
title: "ValueNotifierDemo",
home: new Scaffold(
body: new Center(
child: new Text(_valueNotifier.value.toString()),
),
floatingActionButton: new FloatingActionButton(
onPressed: () {
///修改值
_valueNotifier.value++;
},
child: new Icon(Icons.add),
),
),
);
}
}
实现原理通过源码来看,ValueNotifier
/// A [ChangeNotifier] that holds a single value.
///
/// When [value] is replaced with something that is not equal to the old
/// value as evaluated by the equality operator ==, this class notifies its
/// listeners.
class ValueNotifier<T> extends ChangeNotifier implements ValueListenable<T> {
/// Creates a [ChangeNotifier] that wraps this value.
ValueNotifier(this._value);
/// The current value stored in this notifier.
///
/// When the value is replaced with something that is not equal to the old
/// value as evaluated by the equality operator ==, this class notifies its
/// listeners.
@override
T get value => _value;
T _value;
set value(T newValue) {
if (_value == newValue)
return;
_value = newValue;
notifyListeners();
}
@override
String toString() => '${describeIdentity(this)}($value)';
}
ChangeNotifier
class ChangeNotifier implements Listenable {
ObserverList<VoidCallback> _listeners = ObserverList<VoidCallback>();
///...
@override
void addListener(VoidCallback listener) {
assert(_debugAssertNotDisposed());
_listeners.add(listener);
}
@override
void removeListener(VoidCallback listener) {
assert(_debugAssertNotDisposed());
_listeners.remove(listener);
}
@mustCallSuper
void dispose() {
assert(_debugAssertNotDisposed());
_listeners = null;
}
@protected
@visibleForTesting
void notifyListeners() {
assert(_debugAssertNotDisposed());
if (_listeners != null) {
final List<VoidCallback> localListeners = List<VoidCallback>.from(_listeners);
for (VoidCallback listener in localListeners) {
try {
if (_listeners.contains(listener))
listener();
} catch (exception, stack) {
///...
}
}
}
}
}
和上一篇文章提到的 scoped_model
库的监听原理基本一直,也是使用观察者模式。ValueNotifier
继承与 ChangeNotifier
,里面维护了一个_value
值,就是我们需要监听的值,在 set value
方法里可以看到,当新的值和旧的值不等的时候会调用 notifyListeners
。notifyListeners
里面循环遍历所有的监听方法并调用,所以只要修改了值调用了 set_value
就会回调所有的监听。
ChangeNotifier
主要是在组件内部的监听,如果是组件与组件之间可能更多的是使用 scoped_model
、flutter_redux
、provider
等相关的库了。