目录
前言
GetX 是 Flutter 上的一个轻量且强大的解决方案,提供了状态管理、依赖注入和路由管理等功能。在Flutter的开发过程中,越来越多的人开始选择使用GetX。
今天这篇博客主要通过实例和代码记录下GetX的用法,共同学习,共同进步。
图1.GetX官方logo
1.安装
首先我们去pub.dev 搜索了一下,我们看到排名第一的get就是我们今天要登场的主角getX。
图2.GetX搜索
写这篇博客的时候,我本地的Flutter使用的是最新版本的flutter,版本信息如下:
图3.本地Flutter环境配置
和其它插件的安装方式相同,我们首先将GetX添加到pubspec.yaml文件中。
dependencies: flutter: sdk: flutter get: ^4.6.6
然后终端运行Pub get命令,安装Getx。
在需要使用的文件中导入头文件:
import 'package:get/get.dart';
2.经典的计时器Demo
当我们创建完成一个flutter项目之后,会默认生成一个计时器的页面。本文中使用的flutter的例子为getxdemos。
我们从官方提供的一个计时器的例子可以先体验下GetX的用法。
当我们使用GetX实现计时器的例子时候,首先我们声明一个变量用来统计按钮点击的次数。
RxInt counter = 0.obs;
然后在UI中使用到这个变量的组件使用Obx包起来即可实时的获取变化后的counter变量的值。
图4.计时器功能示意图
首页的代码如下:
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class GetXCounterDemo extends StatelessWidget {
GetXCounterDemo({super.key});
RxInt counter = 0.obs;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("计时器",style:TextStyle(fontSize: 18,fontWeight: FontWeight.bold)),
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Obx(() => Text("点击次数:$counter")),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
counter.value++;
},
child: const Text("点击")),
],
),
)
);
}
}
3.GetX响应式变量使用的三种方式
1.使用Rx{Type}
final name = RxString('');
final isLogged = RxBool(false);
final count = RxInt(0);
final balance = RxDouble(0.0);
final items = RxList<String>([]);
final myMap = RxMap<String, int>({});
2.使用Rx,规定泛型Rx
我们通过一个demo看一下实例中的用法。
我们有一个Controller类用来处理业务逻辑,这个类中,有两个三个变量,count1,count2,sum,当count1或者count2发生变化的时候,sum变量自动更新。
final name = Rx<String>('');
final isLogged = Rx<Bool>(false);
final count = Rx<Int>(0);
final balance = Rx<Double>(0.0);
final number = Rx<Num>(0)
final items = Rx<List<String>>([]);
final myMap = Rx<Map<String, int>>({});
自定义类 - 可以是任何类
final user = Rx<User>();
3.添加Obx作为value的属性
final name = ''.obs;
final isLogged = false.obs;
final count = 0.obs;
final balance = 0.0.obs;
final number = 0.obs;
final items = <String>[].obs;
final myMap = <String, int>{}.obs;
自定义类 - 可以是任何类
final user = User().obs;
4.监听自定义类数据的变化
我们通过一个简单的例子看一下 GetX如何监听自定义类的变化。
在这个Demo中,我们点击UI上面的按钮会随机更新城市的名称。我们看一下怎么实现这个功能。
图2.刷新城市名称
1.配置GetX
这里又不懂的话可以往上翻一翻,怎么安装GetX
2.定义数据模型
class GetXCityModel{
RxString cityName = "北京".obs;
RxString randomStr = "".obs;
}
3.更新以及获取自定义类的值
使用Obx包裹我们的Widget,即可得到实时的变量。
import 'package:english_words/english_words.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class GetXCityModel{
RxString cityName = "北京".obs;
RxString randomStr = "".obs;
}
class GetXBasicVariablePage extends StatelessWidget {
GetXBasicVariablePage({super.key});
var cityModel = GetXCityModel();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("响应式变量",style:TextStyle(fontSize: 18,fontWeight: FontWeight.bold)),
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Obx(() => Text("城市名称:${cityModel.cityName}",)),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
cityModel.cityName.value = WordPair.random().asPascalCase;
},
child: const Text("随机更新城市名称")),
],
),
)
);
}
}
4.GetXController的用法
我们在开发的过程中经常遇到数据共享的场景。
例如我们登陆成功之后,服务器会返回用户信息,其它的页面调用接口的时候可能也会用到用户信息中的某个属性(token等)。
GetXController的出现让这个功能变得十分的简单。
GetxController常用的API有创建和获取方法。
常用的实例化GetxController的方法如下:
GetXCountController controller = Get.put(GetXCountController());
使用GetxController的方法如下:
GetXCountController controller = Get.find();
我们修改一下前面的定时器的例子,点击定时器的首页,可以跳转到定时器详情页面,两个页面之间共享点击次数。
第一个页面点击+,计时器点击次数+1,详情页面点击按钮,计时器几点次数-1。
我们看一下如何实现这个功能。
图3.计时器实例
1.配置GetX
yaml文件配置GetX,修改下main函数。
2.把业务代码封装到GetxController中
在我们这个实例中,仅有一个count变量,业务中可能会操作计时器的次数,因此我们封装了increment和deIncrement方法用来控制点击次数。这里注意的是我们要更新GetxController中的变量的时候要调用update方法。
import 'package:get/get.dart';
class GetXCountController extends GetxController{
var count = 0.obs;
void increment(){
count++;
update();
}
void decrement(){
count--;
update();
}
}
3.更新GetXController
当我们需要更新GetXController的时候,调用Get.put方法获取GetxController实例。
GetXCountController controller = Get.put(GetXCountController());
完整的代码如下:
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:getx/stateManager/counter/getX_counterController.dart';
class GetXCounterDemo extends StatelessWidget {
GetXCounterDemo({super.key});
GetXCountController controller = Get.put(GetXCountController());
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("计时器",style:TextStyle(fontSize: 18,fontWeight: FontWeight.bold)),
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Obx(() => Text("点击次数:${controller.count}")),
const SizedBox(height: 20),
ElevatedButton(
onPressed: () {
Get.toNamed("/counterDetail");
},
child: const Text("跳转下一个页面")),
],
),
),
floatingActionButton: FloatingActionButton(child: const Icon(Icons.add),onPressed: (){
controller.increment();
},),
);
}
}
4.获取GetXController中的值
在定时器的详情页面,我们调用Get.find方法,找到GetXController中的变量。
GetXCountController controller = Get.put(GetXCountController());
完整代码如下:
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:getx/stateManager/counter/getX_counterController.dart';
class GetXCounterDetailDemo extends StatelessWidget {
GetXCounterDetailDemo({super.key});
GetXCountController controller = Get.find<GetXCountController>();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("计时器详情",style:TextStyle(fontSize: 18,fontWeight: FontWeight.bold)),
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Obx(() => Text("上一个页面点击次数:${controller.count}")),
const SizedBox(height: 20),
],
),
),
floatingActionButton: FloatingActionButton(child: const Icon(Icons.minimize),onPressed: (){
controller.decrement();
},),
);
}
}
5.GetX Binding
当我们使用GetX进行状态管理的时候,每次实例化一个控制器的时候,太麻烦了。为了解决这个问题,GetX还提供了Bing机制去简化这个问题。
还有一个问题就是在我们的页面非常复杂的时候,有可能同一个GetxController会被多次初始化,这样的话app就会报错。
图4.进入定时器详情页面的两种方式
例如在本篇博客的实例代码中,有这么一个页面,当我点击UI上的第一个页面的时候,创建了一个CounController实例,进入计时器首页之后,点击页面上的一个按钮进入了计时器详情页面。这个时候逻辑是OK的。此时定时器的主页和详情页面共享一个GetxController。
某一天新来了一个程序员,点击了第三个按钮,也进入了定时器详情页面,此时他不懂之前的逻辑,进入详情页面之后,把使用Controller的代码改成了创建GetxController。
那么这个时候就会发现点击第三个页面进入计时器页面的时候,GetXController里面的数据被初始化了。
为了解决这个问题,今天的主角GetXBinding出现了。
上面的例子中,我们用到了Get.put方法去实例化一个GetxController。那么除了Get.put之外,GetX还提供了以下一种实例化GetxController的方法。
- Get.put():不使用控制器实例也会被创建
- Get.lazyPut():懒加载的方式创建实例,之后在使用的时候才会被创建
- Get.putAsync():Get.put()的异步版本
- Get.create():每次使用都会创建一个新的实例。
当我们使用Bindings绑定GetxController之后,我们需要使用GetxController的地方直接使用下面的代码即可,避免了我们调用Get.put方法。
final controller = Get.find<GetXCountController>();