simple_builder.dart
3.27 KB
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
import 'dart:async';
import 'dart:collection';
import 'package:flutter/widgets.dart';
import 'get_state.dart';
typedef ValueBuilderUpdateCallback<T> = void Function(T snapshot);
typedef ValueBuilderBuilder<T> = Widget Function(
T snapshot, ValueBuilderUpdateCallback<T> updater);
/// Manages a local state like ObxValue, but uses a callback instead of a Rx value.
///
/// Example:
/// ```
/// ValueBuilder<bool>(
/// initialValue: false,
/// builder: (value, update) => Switch(
/// value: value,
/// onChanged: (flag) {
/// update( flag );
/// },),
/// onUpdate: (value) => print("Value updated: $value"),
/// ),
/// ```
class ValueBuilder<T> extends StatefulWidget {
final T initialValue;
final ValueBuilderBuilder builder;
final void Function() onDispose;
final void Function(T) onUpdate;
const ValueBuilder({
Key key,
this.initialValue,
this.onDispose,
this.onUpdate,
@required this.builder,
}) : super(key: key);
@override
_ValueBuilderState<T> createState() => _ValueBuilderState<T>();
}
class _ValueBuilderState<T> extends State<ValueBuilder<T>> {
T value;
@override
void initState() {
super.initState();
value = widget.initialValue;
}
@override
Widget build(BuildContext context) => widget.builder(value, updater);
void updater(T newValue) {
if (widget.onUpdate != null) {
widget.onUpdate(newValue);
}
setState(() {
value = newValue;
});
}
@override
void dispose() {
super.dispose();
widget?.onDispose?.call();
if (value is ChangeNotifier) {
(value as ChangeNotifier)?.dispose();
} else if (value is StreamController) {
(value as StreamController)?.close();
}
value = null;
}
}
// It's a experimental feature
class SimpleBuilder extends StatefulWidget {
final Widget Function(BuildContext) builder;
const SimpleBuilder({Key key, @required this.builder})
: assert(builder != null),
super(key: key);
@override
_SimpleBuilderState createState() => _SimpleBuilderState();
}
class _SimpleBuilderState extends State<SimpleBuilder>
with GetStateUpdaterMixin {
final HashSet<VoidCallback> disposers = HashSet<VoidCallback>();
@override
void dispose() {
super.dispose();
disposers.forEach((element) => element());
}
@override
Widget build(BuildContext context) {
return TaskManager.instance
.exchange(disposers, getUpdate, widget.builder, context);
}
}
class TaskManager {
TaskManager._();
static TaskManager _instance;
static TaskManager get instance => _instance ??= TaskManager._();
// StateSetter _setter;//<old>
GetStateUpdate _setter;
HashSet<VoidCallback> _remove;
// void notify(HashSet<StateSetter> _updaters) { //<old>
void notify(HashSet<GetStateUpdate> _updaters) {
if (_setter != null) {
if (!_updaters.contains(_setter)) {
_updaters.add(_setter);
_remove.add(() => _updaters.remove(_setter));
}
}
}
Widget exchange(
HashSet<VoidCallback> disposers,
// StateSetter setState, //<old>
GetStateUpdate setState,
Widget Function(BuildContext) builder,
BuildContext context,
) {
_remove = disposers;
_setter = setState;
final result = builder(context);
_remove = null;
_setter = null;
return result;
}
}