Flutter状态管理之 Getx

在Flutter开发中状态管理是必不可少的,这个和前端vue的开发类似。flutter原生提供状态管理组件InheritedWidget功能单一,使用场景有限,不过flutter社区有很多优秀的状态管理插件:如笔者一直用的是 provider,它可以实现主题切换、灰色模式、暗黑模式等常见的App的功能。和provider不同的是 Getx更加的强大。我们可以认为Getx是flutter的一个框架,它不仅提供了状态管理,还提供了一些常用的组件、路由管理等。

在使用Getx之前,我们不能着急上马,应认真读一下官方说明,具体详见https://pub.dev/packages/get,在官方的前言里面有瞩目的Getx说明,需要重点关注:

1 性能:Getx专注于性能和资源消耗最小。Getx不使用Streams或ChangeNotifier。
2 Getx允许视图、演示逻辑、业务逻辑、依赖注入和导航的完全解耦。您不需要上下文来在路由之间导航,因此您不依赖小部件树(可视化)。您不需要上下文来通过 inheritedWidget访问控制器/块,因此您可以将演示逻辑和业务逻辑与可视化层完全解耦。您不需要通过MultiProvider将Controllers/Models/Blocs类注入到小部件树中。为此,GetX使用自己的依赖注入功能,将DI与其视图完全解耦。
3 如果您仅将Getx用于状态管理或依赖项管理,则无需使用GetMaterialApp。GetMaterialApp对于与路由和无上下文相关的路由、小组件、国际化、sheet、对话框和高级apis是必要的。

Getx简单使用

导入头文件import 'package:get/get.dart';

1 在mian.dart里面使用GetMaterialApp,其实这样使用Getx对工程的侵入非常大的,所以在项目的初期应该考虑是否使用Getx,而不是随着项目深入使用GetMaterialApp。
2 常用的小组件
2.1 snackbar

Get.snackbar("Snackbar 标题", "欢迎使用Snackbar");

2.2 Dialog

Get.defaultDialog();

2.3 Sheet

Get.bottomSheet()

3 路由router

Getx的路由是调研过程中最大的收获,无论使用flutter自带的路由,还是使用第三方路由,都离不开 context,有些路由需要使用命令才能生成路由,比如auto_route,需要在dev_dependencies;生成路由:aauto_route_generator,flutter packages pub run build_runner build,使用起来比较啰嗦。那么Getx的路由完全和context隔离,只需要Get.to(OhterPageWidget()),就可以跳转界面。to()方法接口也非常丰富,也可以自定义动画,转场动画等。

Future<T?>? to<T>(
    dynamic page, {
    bool? opaque,
    Transition? transition,
    Curve? curve,
    Duration? duration,
    int? id,
    String? routeName,
    bool fullscreenDialog = false,
    dynamic arguments,
    Bindings? binding,
    bool preventDuplicates = true,
    bool? popGesture,
    double Function(BuildContext context)? gestureWidth,
  }) 

除了to()方法外,还可用用toNamed;
在main.dart入口设置路由路径:

 getPages: [
// 首页
         GetPage(name: "/home", page: ()=>Home()),
// 我的
         GetPage(name: "/mine", page: ()=>Minne()),
// 设置
         GetPage(name: "/setting", page: ()=>Setting())
      ],

使用toNamed方法 Get.toNamed("/home")。

4 状态管理

在学习状态管理之前我们需要了解ObxGetxController
Obx关于它官方是这样描述的:

  反应状态管理器(GetX/Obx):
 反应式编程可以疏远许多人,因为它据说很复杂。GetX将反应式编程变成了非常简单的事情:

您不需要创建StreamController。
您不需要为每个变量创建StreamBuilder
您无需为每个州创建类。
您无需为初始值创建get。
你不需要使用代码生成器
使用Get进行反应式编程就像使用setState一样简单。

比如我们观察var name = 'Jonatas Borges'的变化,只需写成var name = 'Jonatas Borges'.obs,除了给属性值后面添加.obs外,还有2种定义Obx变量的方法:
第一种 使用 Rx{Type} 。
final name = RxString('Jonatas Borges');
第二种是使用 Rx,规定泛型 Rx<Type>
final name = Rx<String>('Jonatas Borges');

GetxController主要的作用是用于UI代码与业务逻辑分离开来。下面是个简单的使用:

class Controller extends GetxController {
   var count = 0.obs;
  var age = 18.obs;
  void increment() => count++;
 @override
  void onInit() {
    super.onInit();
    //监听count的值变化
    ever(count, (callback) => print("count"));
    // 监听count age的值
    everAll([count, age], (callback) => print(callback));
    once(count, (callback) => print("count值改变时调用,只执行一次"));
    debounce(count, (callback) => print("1s后调用,防止DDos"));
    interval(count, (callback) => print("忽略1s内所有变动"));
  }
}
...
 appBar: AppBar(
        title: Obx(
// 展示count
          () => Text("Clicks: ${c.count}"),
        ),
      ),

...
floatingActionButton: FloatingActionButton(
// 修改count
        onPressed: () => c.increment(),
        child: Icon(Icons.add),
      ),

uniqueIDGetxController监听过程中,单独在某个GetBuilder上设置。这样更好的管理这个状态。

```tag```:区分不同的控制器来实现不同的功能,减少控制器代码量和重复创建。
 class Controller extends GetxController {
  ...
    void testUniqueID() {
    age += 10;
    //  home_age_id:uniqueID
    update(["home_age_id"]);
  }
  ...
}
 
 final Controller c = Get.put(Controller());
    // print(c);
    return Scaffold(
      body: Column(
        children: [
        //GetBuilder   <Controller> 必须指定 不然会崩溃?。?!
          GetBuilder<Controller>(
            id: "home_age_id",
           tag:"tagxxxx",
            builder: (controller) {
              return Obx(
                () => Text("Clicks: ${c.age}"),
              );
              //  return Text("1111");
              // return Text("年龄值为: ${c.age}",);
            },
          ),
          ElevatedButton(
            onPressed: () => c.testUniqueID(),
            child: Text("增加年龄"),
          )
        ],
      ),
    );

4 国际化配置

国际化配置是状态管理领域的一个重要应用,使用 Getx非??旖莘奖?,是做这种应用的不二选择。

1 自定义个继承与Translations的类,重写keys
class InternationalConfigure extends Translations {
 @override
 // TODO: implement keys
 Map<String, Map<String, String>> get keys => {
       'zh_CN': {
        'hello': "你好, GetX"
       },
       'en_US': {
         'hello': 'Hello GetX',
       },
     };
}
2 在入口出国际化配置
 GetMaterialApp {
   
 ...
  translations: InternationalConfigure(),
     // 设置默认语言
     locale: Locale("zh",'CN'),
     // 在配置错误的情况下 显示的语言
     fallbackLocale: Locale("zh",'CN'),
 ...

}
3 使用国际化配置

首先在状态管理类里实现updateLocale 方法,

class Controller extends GetxController {
     ...
    void changeLanguage(String languageCode, String countryCode) {
    Get.updateLocale(Locale(languageCode, countryCode));
  }
 ...
}

然后就可以切换使用了。

     Text('hello'.tr, style: TextStyle(color: Colors.pink, fontSize: 30)),
  ElevatedButton(
        onPressed: () => c.changeLanguage('zh', 'CN'),
        child: Text("切换中文"),
      ),

      ElevatedButton(
        onPressed: () => c.changeLanguage('en', 'US'),
        child: Text("切换英文"),
      ),
最后编辑于
?著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,992评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,212评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事?!?“怎么了?”我有些...
    开封第一讲书人阅读 159,535评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,197评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,310评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,383评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,409评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,191评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,621评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,910评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,084评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,763评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,403评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,083评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,318评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,946评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,967评论 2 351

推荐阅读更多精彩内容