携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第5天,点击查看活动详情
本文主要介绍GetX中的状态管理的几种方式包括Obx,getx等。
1. Obx
对于我们使用Getx
进行状态管理通常会根据实际情况进行使用,对于页面的局部变化的时候我们可以使用Obx
进行包裹
class Obx extends ObxWidget {
final WidgetCallback builder;
const Obx(this.builder);
@override
Widget build() => builder();
}
使用
/// final _name = "GetX".obs;
/// Obx(() => Text( _name.value )),... ;
这个 WidgetCallback
实际上是一个类似回调的作用,当我们Obx
包裹的builder
中使用的值发生改变的时候,刷新这个组件
ObxWidget
abstract class ObxWidget extends StatefulWidget {
const ObxWidget({Key? key}) : super(key: key);
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties..add(ObjectFlagProperty<Function>.has('builder', build));
}
@override
_ObxState createState() => _ObxState();
@protected
Widget build();
}
抽象类abstract
继承StatefulWidget
因此在状态改变的时候,会通过notifyChildren
通知进行回调刷新widget
class _ObxState extends State<ObxWidget> {
final _observer = RxNotifier();
late StreamSubscription subs;
@override
void initState() {
super.initState();
subs = _observer.listen(_updateTree, cancelOnError: false);
}
void _updateTree(_) {
if (mounted) {
setState(() {});
}
}
@override
void dispose() {
subs.cancel();
_observer.close();
super.dispose();
}
@override
Widget build(BuildContext context) =>
RxInterface.notifyChildren(_observer, widget.build);
}
实际使用
通过拓展让我们的值具有观察者属性
这样当我们的值value
发生改变后就会进行通知刷新我们的Widget
,做到了响应式
。
2.GetBuilder
GetBuilder
通常会搭配GetxController
进行使用,我们看下GetBuilder
的结构
class GetBuilder<T extends GetxController> extends StatefulWidget {
final GetControllerBuilder<T> builder;
final bool global;
final Object? id;
final String? tag;
final bool autoRemove;
final bool assignId;
final Object Function(T value)? filter;
final void Function(GetBuilderState<T> state)? initState,
dispose,
didChangeDependencies;
final void Function(GetBuilder oldWidget, GetBuilderState<T> state)?
didUpdateWidget;
final T? init;
}
也是继承于StatefulWidget
,只是多了个<T extends GetxController>
,让我们可以获取GetxController
中的方法或者数据
。我们看下实际使用:
/// 提交按钮
Widget get _nextItem => Padding(
padding: EdgeInsets.symmetric(horizontal: 15.toPadding),
child: GetBuilder<FeedbackController>(
id: 'next',
builder: (_) => PuppyButton(
onPressed: controller.shouldNext ? controller.feedbackRequest : null,
style: PuppyButtonStyle.style1,
child: const Text('提交'))),
);
这里通常会是通过id
进行更新
,在我们contrller
中处理逻辑完成后主动调用update
进行手动更新
这里是可以添加一个数组进行多个 GetBuilder
触发更新,相比Obx
多了手动的控制。
3. Getx
对于Getx
则可以指定controller
进行关联,同时可以使用state
class GetX<T extends DisposableInterface> extends StatefulWidget {
final GetXControllerBuilder<T> builder;
final bool global;
// final Stream Function(T) stream;
// final StreamController Function(T) streamController;
final bool autoRemove;
final bool assignId;
final void Function(GetXState<T> state)? initState,
dispose,
didChangeDependencies;
final void Function(GetX oldWidget, GetXState<T> state)? didUpdateWidget;
final T? init;
final String? tag;
使用
GetX<FeedbackController>(
init: controller,
initState: (_) {},
builder: (_) => PuppyButton(
onPressed: controller.shouldNext ? controller.feedbackRequest : null,
style: PuppyButtonStyle.style1,
child: const Text('提交'))),
)
适合控制多个控制器
、多种状态
更新,可精细控制初始、局部渲染。
4. ValueBuilder
ValueBuilder
的组成,可以发现比较简单多了关于value
值的变化,可以通过我们初始化的值进行监听变化以及回调从而刷新界面
class ValueBuilder<T> extends StatefulWidget {
final T? initialValue;
final ValueBuilderBuilder<T> 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>();
}
使用
child: ValueBuilder<int>(
initialValue: 10,
builder: (value, updateFun) {
return Column(
children: [
Text('count : ${value.toString()}'),
ElevatedButton(
onPressed:()=> updateFun(value + 1),
child: const Text('add'),
)
],
);
},
onUpdate: (value) => print("Value is updated: $value"),
onDispose: () => print("Widget unmounted"),
)
适合我们简单的局部控件
5. 小结
在GetX中状态管理中使用比较多的通常是Obx
和GetBuilder
,也可以根据实际情况选择自己需要的。