Flutter 系列(十):手撸 GetX 状态管理核心源码实现

一、依赖注入管理核心源码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
class Mobx{
static S put<S>(S dependency,{String? tag}){
return MobxInstance().put<S>(dependency,tag: tag);
}

static S find<S>({String? tag}){
return MobxInstance().find<S>(tag: tag);
}

static bool delete<S>({String? tag}){
return MobxInstance().delete<S>(tag: tag);
}
}

class _InstanceBuilderFactory<T>{

T dependency;

_InstanceBuilderFactory(this.dependency);
}

class MobxInstance{
static MobxInstance? instance;

MobxInstance._();

factory MobxInstance() => instance ??= MobxInstance._();

final _single = <String,_InstanceBuilderFactory>{};

String _getKey(Type type,String? tag){
return tag == null ? type.toString() : type.toString() + tag;
}

S put<S>(S dependency,{String? tag}){
final newKey = _getKey(S, tag);
_single.putIfAbsent(newKey, () => _InstanceBuilderFactory(dependency));
return find<S>(tag: tag);
}

S find<S>({String? tag}){
final newKey = _getKey(S, tag);
if(_single.containsKey(newKey)){
return _single[newKey]!.dependency;
}
throw '"$newKey" not found';
}

bool delete<S>({String? tag}){
final newKey = _getKey(S, tag);
if(_single.containsKey(newKey)){
_single.remove(newKey);
print('"$newKey" removed success');
return true;
}
print('"$newKey" Already removed');
return false;
}
}

二、GetBuilder + Controller.update 核心源码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
typedef MobXCallback = void Function();
//监听器
mixin MobxNotifier{
final _updaters = <MobXCallback>[];
final _updatersGroupIds = <Object?,List<MobXCallback>>{};

void notifyUpdate(){
if(_updaters.isNotEmpty){
for (var element in _updaters) {
element();
}
}
}

void notifyIdUpdate(Object? id){
if(_updatersGroupIds.isEmpty)return;

if(_updatersGroupIds.containsKey(id)){
var listGroup = _updatersGroupIds[id];
listGroup?.forEach((element) {
element();
});
}
}

void removeListener(MobXCallback callback){
if(_updaters.contains(callback)){
_updaters.remove(callback);
}
}

void removeListenerId(Object? id,MobXCallback callback){
if(_updatersGroupIds.containsKey(id)){
_updatersGroupIds[id]?.remove(callback);
}
_updaters.remove(callback);
}

void addListener(MobXCallback callback){
_updaters.add(callback);
}

void addListenerId(Object? id,MobXCallback callback){
_updatersGroupIds[id] ??= <MobXCallback>[];
_updatersGroupIds[id]?.add(callback);
}

void dispose(){
print('notifier dispose');
_updaters.clear();
_updatersGroupIds.clear();
}
}
//Controller 基类
class MobxController with MobxNotifier {
void update([List<Object>? ids]) {
if (ids == null) {
notifyUpdate();
} else {
for (var element in ids) {
notifyIdUpdate(element);
}
}
}
}

typedef MobControllerBuilder<T extends MobxController> = Widget Function(T controller);
//MobxBuilder
class MobxBuilder<T extends MobxController> extends StatefulWidget {
final MobControllerBuilder<T> builder;
final Object? id;
final String? tag;
final bool autoRemove;

const MobxBuilder({Key? key, required this.builder, this.id, this.tag, this.autoRemove = true}) : super(key: key);

@override
State<MobxBuilder> createState() => _MobxBuilderState<T>();
}

class _MobxBuilderState<T extends MobxController> extends State<MobxBuilder<T>> {

late T controller;

@override
void initState() {
super.initState();

controller = MobxInstance().find<T>(tag: widget.tag);
if(widget.id == null){
controller.addListener(() {
if(mounted){
setState(() {

});
}
});
}else{
controller.addListenerId(widget.id, () {
if(mounted){
setState(() {

});
}
});
}
}

@override
void dispose() {
if(widget.autoRemove){
MobxInstance().delete(tag: widget.tag);
}
controller.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
return widget.builder(controller);
}
}

三、 Obx + obs 核心源码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
import 'package:flutter/material.dart';

typedef MyVoidCallback = void Function();
typedef MyValueGetter<T> = T Function();

class MyRxObservable{

final listeners = <MyVoidCallback>[];


void add(MyVoidCallback listener) => listeners.add(listener);

void remove(MyVoidCallback listener) => listeners.remove(listener);

void notify(){
for (var value in listeners) {
value();
}
}

void dispose(){
listeners.clear();
}
}

class MyRxNotifier{

static MyRxNotifier? proxy;

final myRxObservable = MyRxObservable();
final map = <MyRxObservable,String>{};

bool get canUpdate => map.isNotEmpty;

void addListener(MyRxObservable observable){
if(!map.containsKey(observable)){
observable.add(() {
myRxObservable.notify();
});
map[observable] = '';
}
}

static T notifyChildren<T>(MyRxNotifier myRxNotifier,MyValueGetter<T> builder){
final _observer = MyRxNotifier.proxy;
MyRxNotifier.proxy = myRxNotifier;
final result = builder();
if(!myRxNotifier.canUpdate){
MyRxNotifier.proxy = _observer;
throw 'nofityChildren error exception';
}
MyRxNotifier.proxy = _observer;
return result;
}

}

abstract class MyRx<T>{

MyRxObservable myRxObservable = MyRxObservable();

bool firstRebuild = true;

T _value;

MyRx(this._value);

set value(T value){
if(_value == value && !firstRebuild)return;
firstRebuild = false;
_value = value;

myRxObservable.notify();
}

T get value{
MyRxNotifier.proxy?.addListener(myRxObservable);
return _value;
}
}

class MyRxInt extends MyRx<int>{

MyRxInt(int value) : super(value);

MyRxInt operator +(int num){
value = value + num;
return this;
}

MyRxInt operator -(int num){
value = value - num;
return this;
}
}

extension MyIntExtension on int{
MyRxInt get mbx => MyRxInt(this);
}


class Mbx extends StatefulWidget {

final MyValueGetter<Widget> builder;

const Mbx(this.builder,{Key? key}) : super(key: key);

@override
State<Mbx> createState() => _MbxState();
}

class _MbxState extends State<Mbx> {

MyRxNotifier myRxNotifier = MyRxNotifier();

@override
void initState() {
super.initState();

myRxNotifier.myRxObservable.add(() {
if(mounted){
setState(() {

});
}
});
}

@override
Widget build(BuildContext context) {
return MyRxNotifier.notifyChildren(myRxNotifier, widget.builder);
}
}

class MyEasyBindWidget extends StatefulWidget {
const MyEasyBindWidget(
{Key? key,
this.bind,
this.tag,
this.binds,
this.tags,
required this.child})
: super(key: key);

final Object? bind;
final String? tag;

final List<Object>? binds;
final List<String>? tags;

final Widget child;

@override
State<MyEasyBindWidget> createState() => _MyEasyBindWidgetState();
}

class _MyEasyBindWidgetState extends State<MyEasyBindWidget> {
@override
Widget build(BuildContext context) {
return widget.child;
}

@override
void dispose() {
_closeController();
_closeControllers();
super.dispose();
}

void _closeController() {
if(widget.bind == null){
return;
}

var key = widget.bind.runtimeType.toString() + (widget.tag ?? '');
MyEasy.delete(key: key);
}

void _closeControllers() {
if(widget.binds == null){
return;
}

for(int i = 0; i < widget.binds!.length; i++){
var type = widget.binds![i].runtimeType.toString();
if(widget.tags == null || widget.tags?.isEmpty == true){
MyEasy.delete(key: type);
}else{
var key = type + (widget.tags![i]);
MyEasy.delete(key: key);
}
}
}
}

四、效果验证

五、总结


Flutter 系列(十):手撸 GetX 状态管理核心源码实现
https://sweetying520.github.io/2022/11/20/Flutter 系列(十):手撸 GetX 状态管理核心源码实现/
作者
sweetying
发布于
2022年11月20日
许可协议