Flutter GetX状态管理原理

前言

我们知道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进行刷新了.

相关推荐
漂流瓶jz6 小时前
Webpack如何实现万物皆可import?loader的使用/配置/手写实践
前端·javascript·webpack
ZC跨境爬虫6 小时前
跟着 MDN 学CSS day_41:显式轨道、隐式网格与区域命名放置
前端·javascript·css·ui·交互
修己xj7 小时前
告别手动存图!这款叫 Fatkun 的浏览器插件,简直是素材收集神器
前端
针叶7 小时前
Google Play加固保护导致的崩溃
android·安全·google
袋鼠云数栈8 小时前
从前端到基础设施,ACOS 如何打通企业全链路可观测
运维·前端·人工智能·数据治理·数据智能
AskHarries8 小时前
系统提示词、开发者指令和用户输入的优先级
java·前端·数据库
Moment8 小时前
长上下文会最终杀死 Rag 吗?
前端·javascript·后端
qcx238 小时前
【系统学AI】25 论文导读 ①:两篇改变 AI 的开山之作——Attention Is All You Need & ReAct
前端·人工智能·react.js·transformer
执明wa9 小时前
Android Studio 项目目录结构全方位详解
android·ide·android studio
kyriewen9 小时前
大文件上传最全指南:分片、断点续传、秒传,一篇就够了
前端·javascript·面试