Flutter之GetX之GetBuilder

发布时间 2023-04-05 14:06:40作者: R1cardo

Flutter之GetX之GetBuilder

GetX是Flutter的一个非常强力的三方库,包含了非常多的功能,比如状态管理、路由管理、国际化、路由中间件、主题、数据库等等

今天简单介绍一下状态管理中的GetBuilder实现

有关状态管理

当你的 Flutter 应用的状态发生改变时(例如,用户在设置界面中点击了一个开关选项)你改变了状态,这将会触发用户界面的重绘。去改变用户界面本身是没有必要的(例如 widget.setText )—你改变了状态,那么用户界面将重新构建。Flutter 应用是 声明式 的,这也就意味着 Flutter 构建的用户界面就是应用的当前状态。

状态类

GetX 中称之为 Controller,需要继承GetxController,当状态发生改变的时候,调用 update 方法即可通知依赖状态的组件进行刷新。

实现最简单的计数器demo

class CounterController extends GetxController {
  int _counter = 0;
  
  get counter => _counter;

  void increment() {
    _counter++;
    update();
  }
}

视图界面

界面层在需要使用状态的地方使用 GetBuilder 包裹,然后就可以使用 Controller 访问状态对象和操作状态方法了。其中GetBuilder只需要两个参数:

init:初始状态对象,在这里可以完成状态对象的初始化。

builder 方法:这个方法用于构建依赖状态的组件树,方法携带状态对象参数,因此下面的组件可以访问到状态对象。而且一旦状态对象通过 update 方法通知有更新时,依赖状态对象的组件就会被刷新。

Widget build(BuildContext context) {
  return GetBuilder<CounterController>(
    init: CounterController(),
    builder: (controller) => Scaffold(
      appBar: AppBar(
        title: Text('GetX计数器'),
      ),
      body: Center(
        child: Text(
          '${controller.counter}',
          style: TextStyle(
            color: Colors.blue,
            fontSize: 24.0,
          ),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: () {
          controller.increment();
        },
      ),
    ),
  );
}

以上代码有点问题,GetBuilder包住了整个Scaffold,我们没必要把不需要刷新的组件包住

可以改成

Widget build(BuildContext context) {
return Scaffold(
  appBar: AppBar(
    title: Text('GetX计数器'),
  ),
  body: Center(
    child: GetBuilder<CounterController>(
      init: CounterController(),
      builder: (_) => Text(
        '${CounterController.to.counter}',
        style: TextStyle(
          color: Colors.blue,
          fontSize: 24.0,
        ),
      ),
    ),
  ),
  floatingActionButton: FloatingActionButton(
    child: Icon(Icons.add),
    onPressed: () {
      CounterController.to.increment();
    },
  ),
);

当只包住需要刷新的Text组件时,按钮的点击方法和GetBuilder在同一个层级,没办法访问到buidler中的controller,这时候可以在controller中定义一个静态的别名方法

static CounterController get to => Get.find();

直接通过CounterController.to就可以访问到,但是要用Get.find()的话必须要先用Get.put()或者Get.LazyPut()注册依赖,然后就可以通过CounterController.to全局访问了