前言
目前,Flutter有几种状态管理器。但是,它们中的大多数都涉及到使用ChangeNotifier来更新widget,这对于中大型应用的性能来说是一个很糟糕的方法。 Getx 是一个用于 Flutter 应用程序的轻量级、高性能的状态管理库,它提供了简单而强大的工具,帮助开发者更轻松地处理应用程序的状态、依赖注入、导航以及其他常见的 Flutter 开发任务。 Get有两个不同的状态管理器:响应式状态管理器、简单的状态管理器。
1.响应式状态管理器
Getx 使用了一种称为"响应式状态管理"的方法,它通过将数据变成可观察的(observable)来实现。这使得当数据发生变化时,相关的部件能够自动更新。以下是 Getx 中响应式状态管理的核心概念:
1.1 Obx(Observer)
在 Getx 中,可以使用 Obx 部件来包裹相关 UI 代码,以便在状态发生变化时进行更新。Obx 接受一个回调函数,这个回调函数中包含需要根据状态变化来更新的 UI 代码。
Obx(() => Text("Count: ${myController.count}"))
Text 部件会在 myController.count 发生变化时自动更新。
1.2 Rx 类型
Getx 使用 Rx 类型来实现可观察对象。比如,在控制器中,可以使用 RxInt、RxString、RxList 等类型来定义可观察的变量。这些类型有一个 .obs 扩展方法,用于将普通变量转换为可观察的。 示例:
var count = 0.obs; // RxInt 类型的可观察变量
//第一种 使用 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>({});
//第二种是使用 Rx,规定泛型 Rx
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>();
//第三种 更实用、更简单、更可取的方法,只需添加 .obs 作为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;
2.Flutter Getx 简单的状态管理(依赖管理) GetxController
Get有一个简单而强大的依赖管理器,它允许你只用1行代码就能检索到与你的Bloc或Controller相同的类,无需Provider context,无需inheritedWidget。
Controller controller = Get.put(Controller());
// 而不是 Controller controller = Controller();
在使用的时候也仅需一行代码就能找到对应的控制器
Controller controller = Get.find();
//是的,它看起来像魔术,Get会找到你的控制器,并将其提供给你。你可以实例化100万个控制器,Get总会给你正确的控制器。
补充: 在Getx中,Get.find 的作用是查找并返回注册在Getx依赖注入系统中的控制器实例。一般情况下,一次 Get.put(MyController()) 调用将会注册一个控制器实例,并且之后你可以在任何地方使用 Get.find<MyController>() 来获取该实例。
GetxController 在被注销或者上下文被销毁时才会从 Getx 的依赖注入系统中移除。所以,如果你在应用的某个地方使用了 Get.put(MyController()) 注册了一个控制器,该控制器将会一直存在,直到你显式地调用 Get.delete(MyController()) 或者其所在的上下文被销毁。
3.GetX Binding
需求:所有页面都要使用状态管理
我们经常使用 Get.put(MyController()) 来进行控制器实例的创建,这样我们就算 不使用控制器实例也会被创建,其实 GetX 还提供很多创建实例的方法,可根据不同的业务来进行创建,下面简单介绍一下几个最常用的
- Get.put(): 不使用控制器实例也会被创建
- Get.lazyPut(): 懒加载方式创建实例,只有在使用时才创建
- Get.putAsync(): Get.put() 的异步版版本
- Get.create(): 每次使用都会创建一个新的实例
Bindings 是 GetX 中用于绑定控制器的类。通过继承 Bindings 类,可以实现在页面生命周期内自动绑定和解绑控制器。以下是一个简单的例子:
第一步:声明需要进行的绑定控制器类
import 'package:get/get.dart';
class MyController extends GetxController {
var count = 0.obs;
void increment() {
count++;
}
}
第二步:创建binding
// 创建bindings
class MyBinding implements Bindings {
@override
void dependencies() {
Get.lazyPut<MyController>(() => MyController());
//... 其它控制器
}
}
第三步:绑定到路由中
GetPage(
name: '/my',
page: () => MyPage(),
binding: MyBinding(),
),
==GetPage还有bindings 属性,可绑定多个控制器==
第四步:使用 GetView
GetView 是一个基类,用于创建有状态的页面,同时自动处理控制器的绑定和解绑。以下是一个简单的例子:
import 'package:get/get.dart';
class MyHomePage extends GetView<MyController> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('GetView Example'),
),
body: Center(
child: Obx(() => Text('Count: ${controller.count}')),
),
);
}
}
当页面创建时,GetX 会自动创建并绑定 MyController 控制器。当页面销毁时,GetX 会自动解绑控制器。