深入解析 Flutter GetX
深入解析 Flutter GetX:从原理到实战
GetX 是 Flutter 中一个轻量级且功能强大的状态管理、路由管理和依赖注入框架。它以简单、快速、高效著称,适合从小型到大型项目的开发需求。GetX 的设计理念是一体化解决方案,通过一个框架解决状态管理、路由管理和依赖注入的问题。
1. 什么是 GetX?
1.1 GetX 的核心概念
- 状态管理:通过响应式编程实现高效的状态管理。
- 路由管理:无需
BuildContext,支持命名路由和动态路由。 - 依赖注入:通过
Get.put、Get.lazyPut等方法实现依赖注入。
1.2 GetX 的优点
- 简单易用:API 简洁,学习曲线低。
- 高性能:响应式状态管理,支持局部刷新。
- 一体化解决方案:集成状态管理、路由管理和依赖注入。
- 无上下文限制:无需
BuildContext,可以在任何地方访问状态和路由。
2. GetX 的核心原理
2.1 GetX 的三大核心模块
- 状态管理:
- 支持响应式状态管理(
Rx)和简单状态管理(GetBuilder)。
- 支持响应式状态管理(
- 路由管理:
- 支持命名路由、动态路由和路由守卫。
- 依赖注入:
- 通过
Get.put、Get.lazyPut等方法管理依赖。
- 通过
2.2 GetX 的工作流程
- 状态声明:
- 使用
Rx或Controller声明状态。
- 使用
- 状态消费:
- 使用
Obx或GetBuilder监听状态变化并更新 UI。
- 使用
- 路由管理:
- 使用
Get.to或Get.off实现页面跳转。
- 使用
- 依赖注入:
- 使用
Get.put提供依赖,在任何地方访问。
- 使用
3. GetX 的常见用法
3.1 状态管理
3.1.1 响应式状态管理
示例:计数器应用
import 'package:flutter/material.dart';
import 'package:get/get.dart';// 定义控制器
class CounterController extends GetxController {var count = 0.obs; // 响应式变量void increment() {count++;}
}void main() {runApp(MyApp());
}class MyApp extends StatelessWidget {Widget build(BuildContext context) {return GetMaterialApp(home: CounterHomePage(),);}
}class CounterHomePage extends StatelessWidget {final CounterController controller = Get.put(CounterController()); // 注入控制器Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("GetX 示例")),body: Center(child: Obx(() => Text("点击次数:${controller.count}")), // 监听状态变化),floatingActionButton: FloatingActionButton(onPressed: controller.increment,child: Icon(Icons.add),),);}
}
代码解析
- 状态声明:
- 使用
Rx(如0.obs)声明响应式变量。
- 使用
- 状态消费:
- 使用
Obx监听状态变化并更新 UI。
- 使用
- 依赖注入:
- 使用
Get.put提供控制器实例。
- 使用
3.1.2 简单状态管理
示例:计数器应用
class CounterController extends GetxController {int count = 0;void increment() {count++;update(); // 通知监听者更新}
}class CounterHomePage extends StatelessWidget {final CounterController controller = Get.put(CounterController());Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("GetBuilder 示例")),body: Center(child: GetBuilder<CounterController>(builder: (controller) => Text("点击次数:${controller.count}"),),),floatingActionButton: FloatingActionButton(onPressed: controller.increment,child: Icon(Icons.add),),);}
}
代码解析
- 状态声明:
- 使用普通变量声明状态。
- 状态消费:
- 使用
GetBuilder监听状态变化并更新 UI。
- 使用
- 状态更新:
- 调用
update方法通知监听者更新。
- 调用
3.2 路由管理
3.2.1 基本用法
示例:页面跳转
class HomePage extends StatelessWidget {Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("首页")),body: Center(child: ElevatedButton(onPressed: () {Get.to(DetailsPage()); // 跳转到详情页},child: Text("跳转到详情页"),),),);}
}class DetailsPage extends StatelessWidget {Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("详情页")),body: Center(child: ElevatedButton(onPressed: () {Get.back(); // 返回上一页},child: Text("返回首页"),),),);}
}
代码解析
- 页面跳转:
- 使用
Get.to跳转到新页面。
- 使用
- 页面返回:
- 使用
Get.back返回上一页。
- 使用
3.2.2 命名路由
示例:命名路由跳转
void main() {runApp(MyApp());
}class MyApp extends StatelessWidget {Widget build(BuildContext context) {return GetMaterialApp(initialRoute: '/',getPages: [GetPage(name: '/', page: () => HomePage()),GetPage(name: '/details', page: () => DetailsPage()),],);}
}class HomePage extends StatelessWidget {Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("首页")),body: Center(child: ElevatedButton(onPressed: () {Get.toNamed('/details'); // 跳转到详情页},child: Text("跳转到详情页"),),),);}
}class DetailsPage extends StatelessWidget {Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("详情页")),body: Center(child: ElevatedButton(onPressed: () {Get.back(); // 返回上一页},child: Text("返回首页"),),),);}
}
代码解析
- 路由配置:
- 使用
GetPage配置命名路由。
- 使用
- 命名路由跳转:
- 使用
Get.toNamed跳转到命名路由。
- 使用
3.2.3 路由守卫
示例:登录验证
class AuthMiddleware extends GetMiddleware {RouteSettings? redirect(String? route) {final isLoggedIn = false; // 模拟登录状态if (!isLoggedIn) {return RouteSettings(name: '/login');}return null;}
}void main() {runApp(MyApp());
}class MyApp extends StatelessWidget {Widget build(BuildContext context) {return GetMaterialApp(initialRoute: '/',getPages: [GetPage(name: '/', page: () => HomePage()),GetPage(name: '/details', page: () => DetailsPage(), middlewares: [AuthMiddleware()]),GetPage(name: '/login', page: () => LoginPage()),],);}
}
代码解析
- 路由守卫:
- 使用
GetMiddleware实现路由拦截。
- 使用
- 重定向:
- 在
redirect方法中检查登录状态,未登录时跳转到登录页。
- 在
3.3 依赖注入
示例:依赖注入
class ApiService {String fetchData() {return "数据加载完成";}
}class HomeController extends GetxController {final ApiService apiService = Get.find();String getData() {return apiService.fetchData();}
}void main() {Get.put(ApiService()); // 注入依赖runApp(MyApp());
}class MyApp extends StatelessWidget {Widget build(BuildContext context) {return GetMaterialApp(home: HomePage(),);}
}class HomePage extends StatelessWidget {final HomeController controller = Get.put(HomeController());Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("依赖注入示例")),body: Center(child: Text(controller.getData()),),);}
}
代码解析
- 依赖注入:
- 使用
Get.put提供依赖。
- 使用
- 依赖获取:
- 使用
Get.find获取依赖实例。
- 使用
4. 项目实战:实现一个电商应用
4.1 功能需求
- 首页:展示商品列表。
- 商品详情页:展示商品详情。
- 购物车页:展示已添加的商品。
4.2 完整代码
class ProductController extends GetxController {var cart = <String>[].obs;void addToCart(String product) {cart.add(product);}
}void main() {runApp(MyApp());
}class MyApp extends StatelessWidget {Widget build(BuildContext context) {return GetMaterialApp(home: ProductListPage(),);}
}class ProductListPage extends StatelessWidget {final ProductController controller = Get.put(ProductController());Widget build(BuildContext context) {final products = ["商品 1", "商品 2", "商品 3"];return Scaffold(appBar: AppBar(title: Text("商品列表"),actions: [IconButton(icon: Icon(Icons.shopping_cart),onPressed: () {Get.to(CartPage());},),],),body: ListView.builder(itemCount: products.length,itemBuilder: (context, index) {final product = products[index];return ListTile(title: Text(product),trailing: ElevatedButton(onPressed: () {controller.addToCart(product);},child: Text("添加到购物车"),),);},),);}
}class CartPage extends StatelessWidget {final ProductController controller = Get.find();Widget build(BuildContext context) {return Scaffold(appBar: AppBar(title: Text("购物车")),body: Obx(() => ListView.builder(itemCount: controller.cart.length,itemBuilder: (context, index) {return ListTile(title: Text(controller.cart[index]),);},)),);}
}
5. 总结
5.1 GetX 的优点
- 简单易用:API 简洁,学习曲线低。
- 高性能:响应式状态管理,支持局部刷新。
- 一体化解决方案:集成状态管理、路由管理和依赖注入。
5.2 实践建议
- 小型项目:使用
GetX的状态管理和路由管理。 - 中型项目:结合依赖注入,构建模块化的状态管理体系。
- 大型项目:合理拆分控制器,避免单一控制器过于复杂。
相关文章:
深入解析 Flutter GetX
深入解析 Flutter GetX:从原理到实战 GetX 是 Flutter 中一个轻量级且功能强大的状态管理、路由管理和依赖注入框架。它以简单、快速、高效著称,适合从小型到大型项目的开发需求。GetX 的设计理念是一体化解决方案,通过一个框架解决状态管理…...
Java 大视界 -- 人才需求与培养:Java 大数据领域的职业发展路径(92)
💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…...
顺序表常用操作和笔试题
1、顺序表的常用操作 1.1 顺序表的创建 如下代码所示:创建了一个默认空间为10的整型顺序表,如果空间不足则会以1.5倍扩容。 List<Integer> list new ArrayList<>(); 创建一个空间为15的整型顺序表 List<Integer> list2 new ArrayL…...
List<Map<String, Object>> 如何对某个字段求和
在Java中,如果你有一个List<Map<String, Object>>的结构,并且你想要对某个特定字段进行求和,你可以使用Java 8的Stream API来简化这个过程。下面是一个示例代码,演示如何对某个字段进行求和。 假设你有一个List<M…...
2024亚马逊数据分析!
整体财务数据23 净销售额:全年净销售额达 6380 亿美元,同比增长 11%。 净利润:全年净利润为 592 亿美元,较上年同期的 304 亿美元增长 95%。 经营活动现金流:经营活动现金流达 1159 亿美元,同比增加了 36…...
foobar2000设置DSP使用教程及软件推荐
foobar2000安卓中文版:一款高品质手机音频播放器 foobar2000安卓中文版是一款备受好评的高品质手机音频播放器。 几乎支持所有的音频格式,包括 MP3、MP4、AAC、CD 音频等。不论是经典老歌还是最新的流行音乐,foobar2000都能完美播放。除此之…...
Apache Logic4j 库反序列化漏洞复现与深度剖析
前言 在渗透测试领域,反序列化漏洞一直是安全研究人员和攻击者关注的焦点。今天,我们将深入探讨 Apache Logic4j 库中的反序列化漏洞,详细了解其原理,并进行完整的复现演示。 一、漏洞原理 Apache Logic4j 库在处理对象的反序列…...
FPGA VIVADO:axi-lite 从机和主机
FPGA VIVADO:axi-lite 从机和主机 TOC在这里插入代码片 前言 协议就不详细讲解了,直接看手册即可。下面主要如何写代码和关键的时序。 此外下面的代码可以直接用于实际工程 一、AXI-LITE 主机 数据转axi lite接口: 读/写数据FIFO缓存 仲裁:…...
LabVIEW 中的 3dgraph.llb库
3dgraph.llb 库位于C:\Program Files (x86)\National Instruments\LabVIEW 2019\vi.lib\Platform目录下,是 LabVIEW 系统里用于 3D 图形相关操作的关键库。它为 LabVIEW 用户提供众多功能,可在应用程序内创建、显示和交互各类 3D 图形,极大增…...
【Linux】文件系统:文件fd
🔥个人主页:Quitecoder 🔥专栏:linux笔记仓 目录 01.回顾C文件接口02.系统文件I/O02.1 openflags 参数(文件打开模式)标记位传参1. 访问模式(必须指定一个)2. 额外控制标志…...
Vue学习记录19
TransitonGroup <TransitionGroup> 是一个内置组件,用于对 v-for 列表中的元素或组件的插入、移除和顺序改变添加动画效果。 和 <Transtion> 的区别 <TranstionGroup> 支持和 <Transtion> 基本相同的 props、CSS过渡 class 和 JavaScript…...
MATLAB更改图论的布局:设置layout
在图论那一章,我们讲过最小生成树和单源最短路径(见:从零开始学数学建模): 以最短路径那节课为例,把绘图pplot那部分代码写为: % plot绘图有很多参数可以设置,使图尽量美观 P plot…...
【分果果——DP(困难)】
题目 分析 分果果题解参考,下面是补充https://blog.csdn.net/AC__dream/article/details/129431299 关于状态 设f[i][j][k]表示第i个人取到的最后一个糖果编号是j,第i-1个人取到的最后一个糖果编号小于等于k时的最大重量的最小值 关于转移方程 关于 j …...
禁止WPS强制打开PDF文件
原文网址:禁止WPS强制打开PDF文件_IT利刃出鞘的博客-CSDN博客 简介 本文介绍如何避免WPS强制打开PDF文件。 方法 1.删除注册表里.pdf的WPS绑定 WinR,输入:regedit,回车。找到:HKEY_CLASSES_ROOT\.pdf删除KWPS.PDF…...
罗技鼠标接收器丢了,怎么用另一个logi接收器重新配对?
1.首先接收器得是logi的,其次看这个接收器是什么类型的,一共有以下3种。(这几种接收器都可以给其他logi鼠标用) 下图左侧带红标的这个(标可能带颜色或者是透明,都一样),叫多设备接收…...
ffmpeg configure 研究2:分析屏幕输出及文件输出的具体过程
author: hjjdebug date: 2025年 02月 17日 星期一 16:57:55 CST description: ffmpeg configure 研究2 分析屏幕输出及文件输出的具体过程 文章目录 0. 执行./configure 命令1. sed: cant read 信息是从哪里来的 ?1.1 find_filters_extern()1.2 find_things_extern() 2. 屏幕输…...
软件内有离线模型,效果也很实用......
今天给大家带来一款超实用的图片画质增强软件,完全不需要联网,随时随地都能用。 图片画质增强 一键增强画质 使用起来也超简单,完全不需要安装。 软件主要有两个功能:图片增强和视频增强。 在使用之前,先确定一下输出…...
Linux下ioctl的应用
文章目录 1、ioctl简介2、示例程序编写2.1、应用程序编写2.2、驱动程序编写 3、ioctl命令的构成4、测试 1、ioctl简介 ioctl(input/output control)是Linux中的一个系统调用,主要用于设备驱动程序与用户空间应用程序之间进行设备特定的输入/…...
如何通过 prometheus-operator 实现服务发现
在之前的章节中,我们讲解了如何编写一个自定义的 Exporter,以便将指标暴露给 Prometheus 进行抓取。现在,我们将进一步扩展这个内容,介绍如何使用 prometheus-operator 在 Kubernetes 集群中自动发现并监控这些暴露的指标。 部署应用 在 Kubernetes 集群中部署我们的自定…...
认识HTML的标签结构
一、HTML的基本概念 1.什么是HTML? ①HTML是描述网页的一种标记语言,也被称为超文本标记语言【并不是一种编程语言】 ②HTML包含了HTML标签和文本内容 ③HTML文档也称为web页面 2.HTML的标签 HTML的标签通常成对出现,HTML文档由标签和受…...
大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...
RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
linux arm系统烧录
1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 (忘了有没有这步了 估计有) 刷机程序 和 镜像 就不提供了。要刷的时…...
2021-03-15 iview一些问题
1.iview 在使用tree组件时,发现没有set类的方法,只有get,那么要改变tree值,只能遍历treeData,递归修改treeData的checked,发现无法更改,原因在于check模式下,子元素的勾选状态跟父节…...
React19源码系列之 事件插件系统
事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...
图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
