马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?立即注册
x
目录
1. 弁言
2.安装和配置 GetX
3.GetX 状态管理的核心概念
1.相应式编程
2.控制器 (Controller)
3.状态 (State)
4.状态更新(State Update)
5. 根本用法示例
1.Obx
2.GetX
3.GetBuilder
4.Workers
1.ever
2.everAll
3.once
4.interval
5.debounce
6.Workers完整示例
5.唯一的ID
1. 弁言
在 Flutter 开发中,状态管理是一个至关重要的概念。它决定了应用的性能和维护性。GetX 是一个强大的 Flutter 包,它提供了高效、简洁的状态管理、依靠管理和路由管理功能。本文将深入探讨 GetX 的状态管理,并展示如何在 Flutter 应用中利用它。
Flutter也有别的的状态管理器,它们有着各自的特点:
- BLoC非常安全和高效,但是对于初学者来说非常复杂,这使得人们无法利用Flutter举行开发。
- MobX比BLoC更容易,而且是相应式的,几乎是完善的,但是你需要利用一个代码生成器,对于大型应用来说,这降低了生产力,因为你需要喝很多咖啡,直到你的代码在flutter clean之后再次准备好(这不是MobX的错,而是codegen真的很慢!)。
- Provider利用InheritedWidget来通报相同的监听器,以此来办理上面陈诉的ChangeNotifier的题目,这意味着对其ChangeNotifier类的任何访问都必须在widget树内。
Get并不是比任何其他状态管理器更好或更差,而是说你应该分析这些要点以及下面的要点来选择是只用Get,还是与其他状态管理器结合利用。Get不是其他状态管理器的敌人,因为Get是一个微框架,而不仅仅是一个状态管理器,它的状态管理功能既可以单独利用,也可以与其他状态管理器结合利用。
2.安装和配置 GetX
要在 Flutter 项目中利用 GetX,需要在 pubspec.yaml 文件中添加 GetX 依靠:。
dependencies:
get: ^4.6.6
然后,在需要利用 GetX 的文件中导入它:
import 'package:get/get.dart';
3.GetX 状态管理的核心概念
1.相应式编程
GetX 的状态管理基于相应式编程,这意味着状态的变化会自动更新依靠该状态的 UI。GetX 通过 Rx 类及其子类(如 RxInt、RxString)实现了相应式编程。
class MyController extends GetxController {
var count = 0.obs;
void increment() {
count++;
}
}
在上面的代码中,count 是一个可观察的整数 (RxInt)。当 count 的值改变时,任何依靠它的 UI 会自动更新。
2.控制器 (Controller)
控制器用于管理状态和业务逻辑。它继续自 GetxController,可以在此中界说可观察变量和方法。
class MyController extends GetxController {
var count = 0.obs;
void increment() {
count++;
}
}
在这个例子中,MyController 管理 count 状态和 increment 方法。
3.状态 (State)
状态是应用步伐的当前数据或信息。在 GetX 中,可以利用 .obs 修饰符来声明可观察变量,并利用 update() 方法手动触发更新。
class MyController extends GetxController {
var count = 0.obs;
void increment() {
count++;
}
}
通过 count 的 .obs 修饰符,count 变成了一个可观察变量。
4.状态更新(State Update)
GetX 提供了多种更新状态的方法,包括 GetBuilder、GetX 和 Obx。
GetBuilder:非反应式,只在 update() 调用时更新。
GetX 和 Obx:反应式,只在依靠的变量变化时更新。
- class HomePage extends StatelessWidget {
- final MyController controller = Get.put(MyController());
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- appBar: AppBar(title: Text('GetX Example')),
- body: Center(
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- GetX<MyController>(
- builder: (controller) {
- return Text('Count: ${controller.count}');
- },
- ),
- ElevatedButton(
- onPressed: controller.increment,
- child: Text('Increment'),
- ),
- ],
- ),
- ),
- );
- }
- }
复制代码 5. 根本用法示例
1.Obx
以下图的效果为例。我们有两个变量,counter1,counter2和sum.此中sum = counter1+counter2.当我们更新counter1大概Counter2此中的一个变量,sum变量就可自动更新。
图1.计时器
我们看看如何实现。
首先我们把变量生成Getx的Rx范例。
下面这个三种写法都是Getx支持的,您可以任选此中一种您喜欢的方式。
- var counter1 = 0.obs;
- final count = Rx<int>(0);
- final counter2 = Rx(0);
复制代码 然后再利用到该变量的Widget外面利用它Obx包起来即可。
完整代码如下:
- import 'package:flutter/material.dart';import 'package:get/get.dart';class ObxDemosPage extends StatelessWidget { ObxDemosPage({super.key}); var counter1 = 0.obs;
- final count = Rx<int>(0);
- final counter2 = Rx(0); // var counter2 = 0.obs; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('ObX Demos'), ), body: Center( child:Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Obx(()=> Text('counter1:${counter1.value.toInt()}'),), ElevatedButton( onPressed: () { counter1.value++; }, child: const Text('counter1++'), ), ], ), const SizedBox(height: 16.0), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Obx(()=> Text('counter2:${counter2.value.toInt()}'),), ElevatedButton( onPressed: () { counter2.value++; }, child: const Text('counter2++'), ), ], ), const SizedBox(height: 16.0), Obx(()=> Text('sum:${counter2.value.toInt()+counter1.value.toInt()}'),), ], ), ), ); }}
复制代码 2.GetX
还是上述图1的功能为例,我们还可以利用GetxController来实现。
顾名思义,controller也就是控制器的意思,这个类的出现是为了减少代码的低耦合。
我们把业务代码放到GetxController中,减少Widget部分的代码。
我们界说一个继续自GetxController的控制器,代码如下:
- class Controller extends GetxController {
- final count1 = 0.obs;
- final count2 = 0.obs;
- // sum 的值为 count1 和 count2 的总和
- int get sum => count1.value + count2.value;
- // 增加 count1 的值
- void incrementCount1() {
- count1.value++;
- }
- // 增加 count2 的值
- void incrementCount2() {
- count2.value++;
- }
- }
复制代码 然后我们利用GetX包在Widget的外层,即可对变量的精准控制。
- class GetXCounterPage extends StatelessWidget {
- GetXCounterPage({super.key});
- // 使用 Get.put 以确保控制器实例在需要时被正确管理
- final Controller controller = Get.put(Controller());
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- appBar: AppBar(
- title: const Text('计时器Demo'),
- ),
- body: Center(
- child: Column(
- mainAxisAlignment: MainAxisAlignment.start,
- children: [
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceEvenly,
- children: [
- GetX<Controller>(
- builder: (controller) {
- print("count 1 rebuild");
- return Text('count1: ${controller.count1.value}');
- },
- ),
- ElevatedButton(
- onPressed: controller.incrementCount1,
- child: const Text('Increment Count1'),
- ),
- ],
- ),
- Row(
- mainAxisAlignment: MainAxisAlignment.spaceEvenly,
- children: [
- GetX<Controller>(
- builder: (controller) {
- debugPrint("count 2 rebuild");
- return Text('count2: ${controller.count2.value}');
- },
- ),
- ElevatedButton(
- onPressed: controller.incrementCount2,
- child: const Text('Increment Count2'),
- ),
- ],
- ),
- GetX<Controller>(
- builder: (controller) {
- debugPrint("sum rebuild");
- return Text('sum: ${controller.sum}');
- },
- ),
- ],
- ),
- ),
- );
- }
- }
复制代码 上述的过程是自动的,也就是当我们调用GexController中的方法之后,被观察的值立即改变。
3.GetBuilder
GetBuilder的用法和GetX根本相同。区别就是假如利用GetBuilder必须手动的调用GetxController的update方法页面才会刷新。
以下图为例,我们我们的控制器有一个count变量,代码如下:
- class GetBuilderController extends GetxController {
- final count = 0.obs;
- void incrementCount() {
- count.value++;
- }
- }
复制代码 当我们点击按钮之后,调用incrementCount方法,count的值并不会马上更新,只有手动的调用update方法,count才会更新。
完整的代码如下:
- import 'package:flutter/material.dart';import 'package:get/get.dart';class GetBuilderController extends GetxController {
- final count = 0.obs;
- void incrementCount() {
- count.value++;
- }
- }class GetBuilderDemosPage extends StatelessWidget { GetBuilderDemosPage({super.key}); // 利用 Get.put 以确保控制器实例在需要时被精确管理 final GetBuilderController controller = Get.put(GetBuilderController()); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('计时器Demo'), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.start, children: [ GetBuilder<GetBuilderController>( builder: (controller) { debugPrint("count rebuild"); return Text('count: ${controller.count.value}'); }, ), ElevatedButton( onPressed: controller.incrementCount, child: const Text('increment'), ), ElevatedButton( onPressed: controller.update, child: const Text('update'), ), ], ), ), ); }}
复制代码
图2.GetBuilder
4.Workers
在 GetX 中,Workers 是一种监控和相应 Rx 范例变量变化的机制。它们可以在变量变化时执行特定的回调函数,帮助开发者简化逻辑处置惩罚和状态更新。Workers 包括以下几种范例:
ever、everAll、once、interval、debounce
1.ever
ever 会在指定的 Rx 变量每次变化时调用回调函数。
- class Controller extends GetxController {
- final count1 = 0.obs;
- final count2 = 0.obs;
- // sum 的值为 count1 和 count2 的总和
- int get sum => count1.value + count2.value;
- // 增加 count1 的值
- void incrementCount1() {
- count1.value++;
- }
- @override
- void onInit() {
- ever(count2, (_) {
- debugPrint("Count changed: $count2");
- });
- super.onInit();
- }
- // 增加 count2 的值
- void incrementCount2() {
- count2.value++;
- }
- }
复制代码 2.everAll
everAll 会在多个指定的 Rx 变量中的恣意一个变化时调用回调函数。
- class MyController extends GetxController {
- var count1 = 0.obs;
- var count2 = 0.obs;
- @override
- void onInit() {
- everAll([count1, count2], (_) {
- print("One of the counts changed: count1 = $count1, count2 = $count2");
- });
- super.onInit();
- }
- void incrementCount1() {
- count1++;
- }
- void incrementCount2() {
- count2++;
- }
- }
复制代码 3.once
once 只会在指定的 Rx 变量第一次变化时调用回调函数。
- class MyController extends GetxController {
- var count = 0.obs;
- @override
- void onInit() {
- once(count, (_) {
- print("Count changed for the first time: $count");
- });
- super.onInit();
- }
- void increment() {
- count++;
- }
- }
复制代码 4.interval
interval 会在指定的 Rx 变量变化时调用回调函数,但在指定时间内只会调用一次,实用于减少频仍更新的场景。
- class MyController extends GetxController {
- var count = 0.obs;
- @override
- void onInit() {
- interval(count, (_) {
- print("Count changed (with interval): $count");
- }, time: Duration(seconds: 1));
- super.onInit();
- }
- void increment() {
- count++;
- }
- }
复制代码 5.debounce
debounce 会在指定的 Rx 变量变化后的一段时间内没有再次变化时调用回调函数,实用于处置惩罚用户输入等场景。
- import 'package:flutter/material.dart';
- import 'package:get/get.dart';
- class MyController extends GetxController {
- var count1 = 0.obs;
- var count2 = 0.obs;
- @override
- void onInit() {
- super.onInit();
- // 每次 count1 变化时都会执行回调
- ever(count1, (_) {
- print("Count1 changed: $count1");
- });
- // 任意一个 count1 或 count2 变化时都会执行回调
- everAll([count1, count2], (_) {
- print("Count1 or Count2 changed: count1 = $count1, count2 = $count2");
- });
- // count1 第一次变化时执行回调
- once(count1, (_) {
- print("Count1 changed for the first time: $count1");
- });
- // count1 变化时每隔1秒执行一次回调
- interval(count1, (_) {
- print("Count1 changed (with interval): $count1");
- }, time: Duration(seconds: 1));
- // count1 变化后1秒内没有再次变化时执行回调
- debounce(count1, (_) {
- print("Count1 changed (debounced): $count1");
- }, time: Duration(seconds: 1));
- }
- void incrementCount1() {
- count1++;
- }
- void incrementCount2() {
- count2++;
- }
- }
- void main() {
- runApp(MyApp());
- }
- class MyApp extends StatelessWidget {
- @override
- Widget build(BuildContext context) {
- return GetMaterialApp(
- home: HomeScreen(),
- );
- }
- }
- class HomeScreen extends StatelessWidget {
- final MyController controller = Get.put(MyController());
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- appBar: AppBar(
- title: Text('GetX Workers Example'),
- ),
- body: Center(
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- Obx(() => Text('Count1: ${controller.count1}')),
- Obx(() => Text('Count2: ${controller.count2}')),
- ElevatedButton(
- onPressed: controller.incrementCount1,
- child: Text('Increment Count1'),
- ),
- ElevatedButton(
- onPressed: controller.incrementCount2,
- child: Text('Increment Count2'),
- ),
- ],
- ),
- ),
- );
- }
- }
复制代码 6.Workers完整示例
以下是一个完整示例,展示了如何在 GetX 中利用 Workers。
- import 'package:flutter/material.dart';
- import 'package:get/get.dart';
- class MyController extends GetxController {
- var count1 = 0.obs;
- var count2 = 0.obs;
- @override
- void onInit() {
- super.onInit();
- // 每次 count1 变化时都会执行回调
- ever(count1, (_) {
- print("Count1 changed: $count1");
- });
- // 任意一个 count1 或 count2 变化时都会执行回调
- everAll([count1, count2], (_) {
- print("Count1 or Count2 changed: count1 = $count1, count2 = $count2");
- });
- // count1 第一次变化时执行回调
- once(count1, (_) {
- print("Count1 changed for the first time: $count1");
- });
- // count1 变化时每隔1秒执行一次回调
- interval(count1, (_) {
- print("Count1 changed (with interval): $count1");
- }, time: Duration(seconds: 1));
- // count1 变化后1秒内没有再次变化时执行回调
- debounce(count1, (_) {
- print("Count1 changed (debounced): $count1");
- }, time: Duration(seconds: 1));
- }
- void incrementCount1() {
- count1++;
- }
- void incrementCount2() {
- count2++;
- }
- }
- void main() {
- runApp(MyApp());
- }
- class MyApp extends StatelessWidget {
- @override
- Widget build(BuildContext context) {
- return GetMaterialApp(
- home: HomeScreen(),
- );
- }
- }
- class HomeScreen extends StatelessWidget {
- final MyController controller = Get.put(MyController());
- @override
- Widget build(BuildContext context) {
- return Scaffold(
- appBar: AppBar(
- title: Text('GetX Workers Example'),
- ),
- body: Center(
- child: Column(
- mainAxisAlignment: MainAxisAlignment.center,
- children: [
- Obx(() => Text('Count1: ${controller.count1}')),
- Obx(() => Text('Count2: ${controller.count2}')),
- ElevatedButton(
- onPressed: controller.incrementCount1,
- child: Text('Increment Count1'),
- ),
- ElevatedButton(
- onPressed: controller.incrementCount2,
- child: Text('Increment Count2'),
- ),
- ],
- ),
- ),
- );
- }
- }
复制代码 5.唯一的ID
假如你想用GetBuilder完善一个widget的更新控件,你可以给它们分配唯一的ID。
GetBuilder<Controller>(
id: 'text', //这里
init: Controller(), // 每个控制器只用一次
builder: (_) => Text(
'${Get.find<Controller>().counter}', //here
),
),
并更新它:
update(['text']);
GetX会自动举行重修,并且只重修利用被更改的变量的小组件,假如您将一个变量更改为与之前相同的变量,并且不意味着状态的更改,GetX不会重修小组件以节流内存和CPU周期(界面上正在表现3,而您再次将变量更改为3。在大多数状态管理器中,这将导致一个新的重修,但在GetX中,假如究竟上他的状态已经改变,那么widget将只被再次重修)
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |