前言
我们知道Flutter UI框架是声明式的,它也有自己的状态管理机制. 例如StatefulWidget中是State就是Widget中的状态对象. 原本状态的维护方式是这样.
scala
class IdentificationCard extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return IdentificationState();
}
}
class IdentificationState extends State<IdentificationCard> {
String date = "555";
String name = "666";
@override
Widget build(BuildContext context) {
return Column(
children: [
Text('date : $date'),
Text('name : $name'),
GestureDetector(onTap: () {
setState(() {
date = "777";
});
}, child: const Text('修改'))],
);
}
}
UI的状态放在State中,在状态发生改变的时候通过setState方法刷新UI.
这样不是很好区分 展示,业务逻辑,数据之间的代码,感觉很乱. 通过引入GetX插件改造后.
scala
/// 状态
class IdentificationState {
RxString date = "555".obs;
RxString name = "666".obs;
}
/// 业务逻辑
class IdentificationController extends GetxController {
IdentificationState state = IdentificationState();
}
/// 展示
class IdentificationCard extends StatelessWidget {
IdentificationController controller = Get.put(IdentificationController());
@override
Widget build(BuildContext context) {
return Obx(() {
return Column(
children: [
Text('date : ${controller.state.date}'),
Text('name : ${controller.state.name}'),
GestureDetector(
onTap: () {
controller.state.date.value = "777";
},
child: const Text('修改'))
],
);
});
}
}
GetX提供的的这套状态管理把展示,业务逻辑,状态的代码分开了,这样看起来就非常的清晰。不过开始用这套框架的时候我觉得很神奇,为啥我加一个Obx就能自动监听状态的改变并且刷新UI了,于是看了下代码了解大概.
Obx如何实现
首先我们来看Obx是个什么
上面我们能够看到出来Obx本质来说是一个StatefulWidget, 并且它也有自己State.
从ObxState中我们能够看到
scss
void _updateTree(_) {
if (mounted) {
setState(() {});
}
}
在_updateTree中会调用setState刷新Widget. updateTree的调用是下面listen中调用.
php
_observer.listen(_updateTree, cancelOnError: false);
我们需要关注RxNotifier具体的实现看看神奇发生的地方.
NotifyManager中实现了一个GetStream
而按照GetStream的解释是,它是一个轻量级的事件流,类似于StreamController。
这样一来我们就明白了Obx实际上是一个StatefulWidget,它里面监听了一个GetStream,一旦GetStream有事件通知,它就会进行setState重新进行Widget的构造.
Rx如何实现
那现在我们关注一下Rx对象的的实现。拿RxString举例子
以上三个截图让我们知道了,Rx对象实际上是一个RxNotifier,那么前面我们提到ObxState中也有一个RxNotifier(_observer)它们实际上都共用同一个GetStream.
如果我们在更改Rx值的时候同时向GetStream中发送事件导致Obx这个StatefulWidget重新构建能说得通了。实际我们看代码能够得出就是这么一个路子。
RxObjectMixin中的实现
ini
mixin RxObjectMixin<T> on NotifyManager<T> {
late T _value;
set value(T val) {
if (subject.isClosed) return;
sentToStream = false;
if (_value == val && !firstRebuild) return;
firstRebuild = false;
_value = val;
sentToStream = true;
subject.add(_value);
}
// 代码省略...
}
我们在给value赋值的时候就是再调用subject.add(_value) 给 GetStream中发送事件,这样一来Obx就能够重新构建了.
总结
这套代码流程看下来后,对GexX的状态管理做一个简单总结,Obx实际一个StatefulWidget,它的State也就是ObxState中监听了GetStream事件流,通过接收GetStream事件流调用setState重新构建Obx,Rx对象在改变value的时候会向GetStream事件流发送事件,这样就会导致Obx进行刷新了.