Flutter学习-GetX-03 状态管理

携手创作,共同成长!这是我参与「掘金日新计划 · 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);
}

实际使用 image.png

通过拓展让我们的值具有观察者属性

image.png

这样当我们的值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进行手动更新

image.png

这里是可以添加一个数组进行多个 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中状态管理中使用比较多的通常是ObxGetBuilder,也可以根据实际情况选择自己需要的。

猜你喜欢

转载自juejin.im/post/7126907225087901704