【源码篇】Flutter GetX深度剖析 | 我们终将走出自己的路(万字图文) (6)

齐活了!GetBuilder添加方法(方法体是setState),update遍历触发所有添加方法

typedef GetStateUpdate = void Function(); class ListNotifier implements Listenable { List<GetStateUpdate?>? _updaters = <GetStateUpdate?>[]; HashMap<Object?, List<GetStateUpdate>>? _updatersGroupIds = HashMap<Object?, List<GetStateUpdate>>(); @protected void refresh() { assert(_debugAssertNotDisposed()); _notifyUpdate(); } void _notifyUpdate() { for (var element in _updaters!) { element!(); } } ... }

如果在update中加了id参数,会走refreshGroup方法,逻辑和refresh几乎一样,差别是对id的判断:有则执行,无则跳过

遍历所有ids,然后执行refreshGroup方法

abstract class GetxController extends DisposableInterface with ListNotifier { void update([List<Object>? ids, bool condition = true]) { if (!condition) { return; } if (ids == null) { refresh(); } else { for (final id in ids) { refreshGroup(id); } } } } class ListNotifier implements Listenable { HashMap<Object?, List<GetStateUpdate>>? _updatersGroupIds = HashMap<Object?, List<GetStateUpdate>>(); void _notifyIdUpdate(Object id) { if (_updatersGroupIds!.containsKey(id)) { final listGroup = _updatersGroupIds![id]!; for (var item in listGroup) { item(); } } } @protected void refreshGroup(Object id) { assert(_debugAssertNotDisposed()); _notifyIdUpdate(id); } } 总结

来看下GetBuilder刷新图示

GetBuilder刷新机制

Obx刷新机制

这套刷新机制,和我们常用的状态管理框架(provider,bloc)以及上面的GetBuilder,在使用上有一些区别

变量上:基础类型,实体以及列表之类的数据类型,作者都封装了一套Rx类型,快捷在数据后加obs

例如:RxString msg = "test".obs(var msg = "test".obs)

更新上:基础类型直接更新数据就行,实体需要以 .update() 的形式

使用上:使用这类变量,一般要加上 .value ,作者也给出一个快捷方式变量后面加个 ()

我不太推荐加 () 的形式,对后续维护项目人太不友好了

Obx刷新机制,最有趣应该就是变量改变后,包裹该变量的Obx会自动刷新!注意喔,仅仅是包裹该变量的Obx会刷新!其它的Obx并不会刷新。

这是怎么做到的呢?

实际上,实现起来很简单

但是,如果没有接触过这个思路,恐怕抓破头,都很难想出来,还能这么玩。。。

使用

简单的来看下使用

logic

class GetCounterRxLogic extends GetxController { var count = 0.obs; ///自增 void increase() => ++count; }

view

class GetCounterRxPage extends StatelessWidget { final GetCounterRxLogic logic = Get.put(GetCounterRxLogic()); @override Widget build(BuildContext context) { return BaseScaffold( appBar: AppBar(title: const Text('计数器-响应式')), body: Center( child: Obx(() { return Text( '点击了 ${logic.count.value} 次', style: TextStyle(fontSize: 30.0), ); }), ), floatingActionButton: FloatingActionButton( onPressed: () => logic.increase(), child: Icon(Icons.add), ), ); } } Rx类变量

此处以 RxInt 为例,来看下其内部实现

先来看下整型后面的拓展 obs ,这是一个扩展类,0.obs 等同 RxInt(0)

extension IntExtension on int { /// Returns a `RxInt` with [this] `int` as initial value. RxInt get obs => RxInt(this); }

来看下RxInt:这地方明确了使用 .value 运行时,会自动返回一个当前实例,并修改相应value数值

class RxInt extends Rx<int> { RxInt(int initial) : super(initial); /// Addition operator. RxInt operator +(int other) { value = value + other; return this; } /// Subtraction operator. RxInt operator -(int other) { value = value - other; return this; } }

来看下父类 Rx

这地方出现了一个很重要的类: _RxImpl

class Rx<T> extends _RxImpl<T> { Rx(T initial) : super(initial); @override dynamic toJson() { try { return (value as dynamic)?.toJson(); } on Exception catch (_) { throw '$T has not method [toJson]'; } } }

_RxImpl 类继承了 RxNotifier 和 with 了 RxObjectMixin

这个类内容是比较庞大的,主要是 RxNotifier 和 RxObjectMixin 内容很多

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zgyyyj.html