• Flutter 全能型选手GetX —— 状态管理


    使用篇
    原理篇

    一、简介

    • Obx:响应式状态管理,当数据源变化时,将自动执行刷新组件的方法
    • GetX:响应式状态管理,当数据源变化时,将自动执行刷新组件的方法
    • GetBuilder:简单状态管理,当数据源变化时,需要手动执行刷新组件的方法,此状态管理器内部实际上是对StatefulWidget的封装,占用资源极少!

    二、GetBuilder

    我们在controller获取数据之后,就会调用controller的update方法来更新界面。如果我们需要刷新对应的界面,就可以
    使用GetBuilder将需要Builder的页面包起来如下:

     GetBuilder<FirstController>(builder: (controller) {
              return Text('第一页');
            })
    
    • 1
    • 2
    • 3

    在controller里如果直接update的话,默认刷新全部,但是如果我们只想刷新部分界面,可以直接在
    GetBuilder的参数加个标识Id,然后和update里方法里的参数id相对应就行了。

       
    class FirstController extends GetxController {
      int count = 0;
    
      updateData() {
        update(['first']);
      }
    }
    
    GetBuilder<FirstController>(
                  builder: (controller) {
                    return Text('第一页');
                  },
                  id: 'first',
                )	
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    三、ValueBuilder

    简化它的工作原理是使用采用更新值的回调。StatefulWidget.setState

     ValueBuilder<bool>(
      initialValue: false,
      builder: (value, updateFn) => Switch(
        value: value,
        onChanged: updateFn, // same signature! you could use ( newValue ) => updateFn( newValue )
      ),
      // if you need to call something outside the builder method.
      onUpdate: (value) => print("Value updated: $value"),
      onDispose: () => print("Widget unmounted"),
    ),
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    四、Getx、Obx和ObxValue

    与ValueBuilder类似,但这是Reactive版本,您传递一个Rx实例(还记得神奇的.obs吗?)并自动更新…是不是很棒?
    obs是Getx提供的一个用来修饰变量的。被obs修饰过的变量,可以不使用GetBuilder,但是需要使用另一个widget,那就是obx,来包裹需要刷新的widget,不需要我们手动去update。

     Obx(() => Text('第一页:${controller.count}')))
     
     class FirstController extends GetxController {
      Rx<int> count = 0.obs;
    
      updateData() {
        // update(['first']);
        count.value++;
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    另外一种形式的写法ObxValue 如下:

    ObxValue(() => Text('第一页:${controller.count}'),count.obs)
    
    • 1

    当然Getx还提供了一个响应式的widget就是Getx,它和Obx都是响应式widget不需要手动update。

    
    class SimplePage extends StatelessWidget {
      const SimplePage({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        Get.put(SimpleController());
        return GetX<SimpleController>(builder: (controller) {
          return Scaffold(
            appBar: AppBar(title: const Text('Simple')),
            body: GestureDetector(
              onTap: () {
                controller.increment();
              },
              child: Center(
                child: Text('${controller.counter.value}'),
              ),
            ),
          );
        });
      }
    }
    
    class SimpleController extends GetxController {
      Rx<int> counter = 0.obs;
    
      void increment() {
        counter.value++;
      }
    }
    
    
    • 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
    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;
    
      const GetX({
        this.tag,
        required this.builder,
        this.global = true,
        this.autoRemove = true,
        this.initState,
        this.assignId = false,
        //  this.stream,
        this.dispose,
        this.didChangeDependencies,
        this.didUpdateWidget,
        this.init,
        // this.streamController
      });
    
    • 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

    当然要说Obx和Getx的区别的话,它提供参数比较多些,其中就包括了一下widget的生命周期。
    如果我们想在widget生命周期做一些事,我觉得就可以 使用这个widget了。

    五、GetView

    GetX 提供了一个快捷的 Widget 用来访问容器中的 controller,即 GetView。GetView是一个继承 StatelessWidget的抽象类,
    GetView 是一个const Stateless的Widget,如果我们只有单个控制器作为依赖项,那我们就可以使用GetView,而不是使用StatelessWidget,并且避免了写Get.Find()。
    可以看到GetView的源码已经帮你写好了。

    abstract class GetView<T> extends StatelessWidget {
      const GetView({Key? key}) : super(key: key);
    
      final String? tag = null;
    
      T get controller => GetInstance().find<T>(tag: tag)!;
    
      @override
      Widget build(BuildContext context);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    然后控制器的注册要写在bindings中,可以看这里 Flutter 全能型选手GetX —— 依赖管理

    六、GetWidget

    GetWidget不是个const Stateless视图,它缓存了一个控制器。由于缓存,不能成为一个 “const Stateless”(因为缓存,所以不能成为一个const Stateless)。当我们使用Get.create(()=>Controller())会在每次调用时生成一个新的Controlle,Get.find()`
    因为我们平时一般不需要缓存控制器,所以一般很少使用。

    七、总结

    一般来说,对于大多数场景都是可以使用响应式变量。但是每个响应式变量(.obs),都需要生成对应的 Stream,如果对象足够多,将生成大量的 Stream,必将对内存造成较大的压力,该情况下,就要考虑使用简单状态管理了

  • 相关阅读:
    Anaconda虚拟环境中打开Jupyter
    面向过程程序设计——循环结构程序设计(2)
    预售拼购模式是什么?有什么优势?
    汇编语言(7)运算指令
    python爬虫动态爬取需点击事件或下一步才可获取的内容
    RK3588平台开发系列讲解(DisplayPort篇)DP相关模式说明
    会议OA项目之我的会议排座&批审功能
    CAPL编程学习笔记--关于on 事件的详细解释
    交换机的作用
    x86 CPU架构
  • 原文地址:https://blog.csdn.net/hjjdehao/article/details/126089756