Flutter GetX 的三种响应式Controller的区别和应用

39 min read

可以在页面当用直接使用响应式数据例如: Demo

但一般是把视图和控制层进行分离,于是就有了 Controller的概念

安装

//pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  get: 

分类

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

大体分两类:

一种是主动执行update 方法,对Widget进行刷新

一种是基于StreamBuilder ,当数据发生更改里自动刷新Widget

区别在于:

  1. 在Widget中使用的方法不同
  2. 内存占用不同

简单控制器例子

class CounterController extends GetxController{
  var count = 0;
  void increase(){
    ++count;
    update(); // 手动刷新
  }
}
class Demo extends StatelessWidget {
  const Demo({Key? key}) : super(key: key);
  
  
  @override
  Widget build(BuildContext context) {
    final counter = Get.put(CounterController());
    return Scaffold(
      appBar: AppBar(title: const Text("GetX"),),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            GetBuilder<CounterController>(
             // init: counter,
              builder: (controller){
                return Text(
                  "count的值为:${counter.count}",
                  style: const TextStyle(color: Colors.redAccent,fontSize: 20),
                );
              },
              initState: (controller){},
              dispose: (controller){},
            ),
            const SizedBox(height: 30,),
            ElevatedButton( // 按钮点击count值++
              onPressed: () => counter.increase(),
              child: const Text("点击count++"),
            ),
          ],
        ),
      ),
    );
  }
}

  • 参数init:因为在加载变量的时候就使用Get.put()生成了CounterController对象,GetBuilder会自动查找该对象,所以,就可以不使用init参数。
  • GetBuilder拥有StatefulWidget所有周期回调,如:initState 、dispose 可以在相应回调内做一些操作。但是比这更好的方法是直接从控制器中使用onInit()和onClose()方法。

响应式状态管理

class CounterController extends GetxController{
  /// 定义了该变量为响应式变量,当该变量数值变化时,页面的刷新方法将自动刷新
  var count = 0.obs;
  /// 自增方法
  void increase() => ++count;
}
class Demo extends StatelessWidget {
  const Demo2({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    /// 通过依赖注入方式实例化的控制器
    final counter = Get.put(CounterController());
    return Scaffold(
      appBar: AppBar(title: const Text("GetX"),),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Obx(() => Text(
              "count的值为:${counter.count}",
              style: const TextStyle(color: Colors.redAccent,fontSize: 20),
            )),
            /*
            GetX<CounterController>(
              init: counter,
              builder: (controller){
                return Text(
                  "count的值为:${controller.count}",
                  style: const TextStyle(color: Colors.redAccent,fontSize: 20),
                );
              },
            ),
            */
            const SizedBox(height: 30,),
            ElevatedButton( // 按钮点击count值++
              onPressed: () => counter.increase(),
              child: const Text("点击count++"),
            ),
          ],
        ),
      ),
    );
  }
}

  • 响应式状态管理器只有当响应式变量的值发生变化时,才会会执行刷新操作,如当变量从“a”再变为“a”,是不会执行刷新操作。
  • final counter = Get.put(CounterController()); 通过依赖注入方式实例化的控制器,不是 Controller controller = Controller(),也不是在正在使用的类中实例化的类,所有它可以在整个App中使用,前提是没有销毁。
  • 使用Get.put()实例化类,使用对当下所有子路由可用。
  • Get.find()找到对应的GetxController