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进行刷新了.

相关推荐
Aileen_0v01 小时前
【玩转OCR | 腾讯云智能结构化OCR在图像增强与发票识别中的应用实践】
android·java·人工智能·云计算·ocr·腾讯云·玩转腾讯云ocr
蟾宫曲3 小时前
在 Vue3 项目中实现计时器组件的使用(Vite+Vue3+Node+npm+Element-plus,附测试代码)
前端·npm·vue3·vite·element-plus·计时器
秋雨凉人心3 小时前
简单发布一个npm包
前端·javascript·webpack·npm·node.js
liuxin334455663 小时前
学籍管理系统:实现教育管理现代化
java·开发语言·前端·数据库·安全
qq13267029403 小时前
运行Zr.Admin项目(前端)
前端·vue2·zradmin前端·zradmin vue·运行zradmin·vue2版本zradmin
江上清风山间明月4 小时前
Flutter DragTarget拖拽控件详解
android·flutter·ios·拖拽·dragtarget
魏时烟4 小时前
css文字折行以及双端对齐实现方式
前端·css
2401_882726485 小时前
低代码配置式组态软件-BY组态
前端·物联网·低代码·前端框架·编辑器·web
web130933203985 小时前
ctfshow-web入门-文件包含(web82-web86)条件竞争实现session会话文件包含
前端·github
胡西风_foxww5 小时前
【ES6复习笔记】迭代器(10)
前端·笔记·迭代器·es6·iterator