flutter 如何实现状态管理?
Flutter 要是实现状态管理wiget必须继承StatefulWidget
,调用setState((){})
,当然getx也不例外,
getx 状态管理
scala
class HomeController extends GetxController {
final count = 0.obs;
}
class HomePage extends GetView<HomeController> {
@override
Widget build(BuildContext context) {
return Center(
child: Obx(() => Text("${controller.currentPage.value}"))
);
}
}
Obx
Obx 继承ObxWidget继承StatefulWidget
scala
abstract class ObxWidget extends StatefulWidget {
const ObxWidget({Key? key}) : super(key: key);
@override
_ObxState createState() => _ObxState();
@protected
Widget build();
}
class _ObxState extends State<ObxWidget> {
//obx的 RxNotifier
///很重要,会有2个RxNotifier
//1.obx的RxNotifier
//Rxint的RxNotifier
final _observer = RxNotifier();
late StreamSubscription subs;
@override
void initState() {
super.initState();
//设置监听
//给getStream 设置参数
//1.创建LightSubscription
//2.onData() = _updateTree 更新widget的方法
//3.加入监听列表
subs = _observer.listen(_updateTree, cancelOnError: false);
}
//更新的关键方法
//猜测当rxint.setValue时,会调用此方法来更新widget
void _updateTree(_) {
if (mounted) {
setState(() {});
}
}
@override
void dispose() {
subs.cancel();
_observer.close();
super.dispose();
}
//通过notifyChildren创建widget
//
@override
Widget build(BuildContext context) =>
RxInterface.notifyChildren(_observer, widget.build);
}
RxNotifier
scss
class RxNotifier<T> = RxInterface<T> with NotifyManager<T>;
//
mixin NotifyManager<T> {
GetStream<T> subject = GetStream<T>();
final _subscriptions = <GetStream, List<StreamSubscription>>{};
bool get canUpdate => _subscriptions.isNotEmpty;
//1.obx_rxnotifier.addlistener(rxInt_getstream)
//2.给rxInt_getstream设置监听
//3.ondata = (data) {
// if (!subject.isClosed) obx_subject.add(data);
// }
//4.当value 值更新时,触发 obx_getsteam的ondata= setstate()更新widget
void addListener(GetStream<T> rxGetx) {
if (!_subscriptions.containsKey(rxGetx)) {
//设置一个监听
final subs = rxGetx.listen(
(data) {
if (!subject.isClosed) subject.add(data);
}
);
final listSubscriptions =
_subscriptions[rxGetx] ??= <StreamSubscription>[];
listSubscriptions.add(subs);
}
}
//
StreamSubscription<T> listen(
void Function(T) onData, {
Function? onError,
void Function()? onDone,
bool? cancelOnError,
}) =>
subject.listen(
onData,
onError: onError,
onDone: onDone,
cancelOnError: cancelOnError ?? false,
);
void close() {
_subscriptions.forEach((getStream, _subscriptions) {
for (final subscription in _subscriptions) {
subscription.cancel();
}
});
_subscriptions.clear();
subject.close();
}
}
GetStream
csharp
class GetStream<T> {
void Function()? onListen;
void Function()? onPause;
void Function()? onResume;
FutureOr<void> Function()? onCancel;
GetStream({this.onListen, this.onPause, this.onResume, this.onCancel});
List<LightSubscription<T>>? _onData = <LightSubscription<T>>[];
bool? _isBusy = false;
FutureOr<bool?> removeSubscription(LightSubscription<T> subs) async {
if (!_isBusy!) {
return _onData!.remove(subs);
} else {
await Future.delayed(Duration.zero);
return _onData?.remove(subs);
}
}
FutureOr<void> addSubscription(LightSubscription<T> subs) async {
if (!_isBusy!) {
return _onData!.add(subs);
} else {
await Future.delayed(Duration.zero);
return _onData!.add(subs);
}
}
int? get length => _onData?.length;
bool get hasListeners => _onData!.isNotEmpty;
//2种情况
//1.rxint 值更新了,执行的时(data){obx_getstream.add()}
//2.obx_stream 执行的是 setstate((){}) 刷新widget
void _notifyData(T data) {
_isBusy = true;
for (final item in _onData!) {
if (!item.isPaused) {
item._data?.call(data);
}
}
_isBusy = false;
}
T? _value;
T? get value => _value;
//1.rxint 当value更新时,调用 _notifyData,
//2.value值更新,触发,obx的getstream 的add,
void add(T event) {
assert(!isClosed, 'You cannot add event to closed Stream');
_value = event;
//
_notifyData(event);
}
bool get isClosed => _onData == null;
void close() {
assert(!isClosed, 'You cannot close a closed Stream');
_notifyDone();
_onData = null;
_isBusy = null;
_value = null;
}
//obx
//1.创建LightSubscription
//2.onData() 更新widget的方法
//3.加入监听列表
// rxInt
//1.把onData加入到监听
/// rxint 也要加入监听
// onData = (data){obx_subject.add(data)}
//加入rxint 的监听列表
//当value更新时
LightSubscription<T> listen(void Function(T event) onData,
{Function? onError, void Function()? onDone, bool? cancelOnError}) {
final subs = LightSubscription<T>(
removeSubscription,
onPause: onPause,
onResume: onResume,
onCancel: onCancel,
)
..onData(onData)
..onError(onError)
..onDone(onDone)
..cancelOnError = cancelOnError;
addSubscription(subs);
onListen?.call();
return subs;
}
Stream<T> get stream =>
GetStreamTransformation(addSubscription, removeSubscription);
}
RxInterface 重点
会给proxy 设置2次notifier
csharp
abstract class RxInterface<T> {
//静态全局可用,
//
static RxInterface? proxy;
StreamSubscription<T> listen(void Function(T event) onData,
{Function? onError, void Function()? onDone, bool? cancelOnError});
static T notifyChildren<T>(RxNotifier observer, ValueGetter<T> builder) {
//1.首次 _observer = null
final _observer = RxInterface.proxy;
//1.给proxy 设置 obx的 rxNotifiter
//上文说到此时有2个rxNotifiter
//此时的是obx的
RxInterface.proxy = observer;
//执行构建widget方法
//看{controller.count.value}
final result = builder();
//reset null
RxInterface.proxy = _observer;
//返回widget
return result;
}
}
0.obs是什么? RxInt
rxint的RxNotifier
controller.count.value执行的是RxObjectMixin.value
class RxInt extends Rx<int> extends _RxImpl<T> extends RxNotifier<T> with RxObjectMixin<T> on NotifyManager<T>
dart
extension IntExtension on int {
RxInt get obs => RxInt(this);
}
RxObjectMixin
ini
mixin RxObjectMixin<T> on NotifyManager<T> {
late T _value;
void refresh() {
subject.add(value);
}
T call([T? v]) {
if (v != null) {
value = v;
}
return value;
}
bool firstRebuild = true;
bool sentToStream = false;
//controller.count.value = 1
//1.执行getStream.add()
////2.rxint 值更新了,执行的时(data){obx_getstream.add()}
//3.obx_stream 执行的是 setstate((){}) 刷新widget
set value(T val) {
if (subject.isClosed) return;
sentToStream = false;
if (_value == val && !firstRebuild) return;
firstRebuild = false;
_value = val;
sentToStream = true;
subject.add(_value);
}
//执行rxint的value
//1.此时的RxInterface.proxy = obx的rxNotifiter,
//2.将rxint的getStream 设置给obx
// obx_rxnotifiter.addListener(rxint_subject)
//
// rxint 加入监听,
// rxint_getstream值的更新触发obx_getsream的setState()更新widget
T get value {
RxInterface.proxy?.addListener(subject);
return _value;
}
Stream<T> get stream => subject.stream;
StreamSubscription<T> listenAndPump(void Function(T event) onData,
{Function? onError, void Function()? onDone, bool? cancelOnError}) {
final subscription = listen(
onData,
onError: onError,
onDone: onDone,
cancelOnError: cancelOnError,
);
subject.add(value);
return subscription;
}
void bindStream(Stream<T> stream) {
final listSubscriptions =
_subscriptions[subject] ??= <StreamSubscription>[];
listSubscriptions.add(stream.listen((va) => value = va));
}
}