Flutter开发 - 使用GetX框架实现类似MVVM架构
回顾原生开发在Android原生开发中通常是使用Databinding实现MVVM架构只需要在gradle中开启databinding的选项然后使用ObservableField或LiveData即可。buildFeatures { dataBinding true }layout xmlns:androidhttp://schemas.android.com/apk/res/android xmlns:apphttp://schemas.android.com/apk/res-auto data variable namem typecom.example.vm.LoginViewModel / /data EditText android:text{m.username}/ /layout在ViewModel中可以定义ObservableField这样界面就可以直接观察了。简单看一下ObservableField的源码其实还有另外的几个类也是类似的功能比如ObservableInt和ObservableBoolean。package androidx.databinding; import androidx.annotation.Nullable; import java.io.Serializable; /** * An object wrapper to make it observable. * p * Observable field classes may be used instead of creating an Observable object. It can also * create a calculated field, depending on other fields: * precodepublic class MyDataObject { * private Context context; * public final ObservableFieldlt;Stringgt; first new ObservableFieldlt;Stringgt;(); * public final ObservableFieldlt;Stringgt; last new ObservableFieldlt;Stringgt;(); * public final ObservableFieldlt;Stringgt; display * new ObservableFieldlt;Stringgt;(first, last) { * #64;Override * public String get() { * return context.getResources().getString(R.string.name, first.get, last.get()); * } * }; * public final ObservableInt age new ObservableInt(); * }/code/pre * Fields of this type should be declared final because bindings only detect changes in the * fields value, not of the field itself. * * param T The type parameter for the actual object. * see ObservableParcelable */ public class ObservableFieldT extends BaseObservableField implements Serializable { static final long serialVersionUID 1L; private T mValue; /** * Wraps the given object and creates an observable object * * param value The value to be wrapped as an observable. */ public ObservableField(T value) { mValue value; } /** * Creates an empty observable object */ public ObservableField() { } /** * Creates an ObservableField that depends on {code dependencies}. Typically, * ObservableFields are passed as dependencies. When any dependency * notifies changes, this ObservableField also notifies a change. * * param dependencies The Observables that this ObservableField depends on. */ public ObservableField(Observable... dependencies) { super(dependencies); } /** * return the stored value. */ Nullable public T get() { return mValue; } /** * Set the stored value. * * param value The new value */ public void set(T value) { if (value ! mValue) { mValue value; notifyChange(); } } }databinding里面的ObservableField类可以帮助我们很好的实现数据的双向绑定通过调用它 的get()方法就可以拿到值了在xml中也可以很方便地使用其值。 这样一种优雅的写法在Flutter中怎么玩呢还是那句话巧妇难为无米之炊首先你得有Flutter的开发环境要不然你也就只能看看了。如果不了解Flutter环境怎么搭建的可以看juejin.cn/post/718557… 这篇文章。那么我们开向幼儿园的车马上就要发车了。不好意思说错了是开往大前端大佬的车。框架搭建我们先大概了解下Flutter项目的项目结构由于这是一个演示Demo我这里就不分包了你们可以写的更优雅。集成get框架就一个命令flutter就是这么简单。flutter pub add get内行人一眼就看出我们肯定是先看main.dart文件。import package:flutter/material.dart; import package:flutter_mvvm_demo/home_binding.dart; import package:flutter_mvvm_demo/main_binding.dart; import package:flutter_mvvm_demo/home_view.dart; import package:flutter_mvvm_demo/main_view.dart; import package:get/get.dart; void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({super.key}); override Widget build(BuildContext context) { return GetMaterialApp( initialRoute: /home, getPages: [ GetPage( name: /home, page: () const HomeView(), binding: HomeBinding(), ), GetPage( name: /main, page: () const MainView(), binding: MainBinding(), ), ], ); } }这个MyApp就是我们程序的入口相当于Application类其实最主要是因为在main()方法中调了一个runApp()方法然后传入了我们的第一个视图。在Flutter中不是管View叫视图。Flutter中的视图有两种一种是有状态的StatefulWidget还有一种是无状态的StatelessWidget。我们这里返回了一个GetMaterialApp里面指定了两个属性。initialRoute代表第一个页面的路由getPages中指定所有的页面。GetPage里面的page指定了这个页面的视图Widget然后使用binding指定依赖注入简单说就是不用在使用的时候new对象直接注入到属性中。import package:flutter_mvvm_demo/home_controller.dart; import package:get/get.dart; class HomeBinding extends Bindings { override void dependencies() { Get.put(HomeController()); } }import package:flutter_mvvm_demo/main_controller.dart; import package:get/get.dart; class MainBinding extends Bindings { override void dependencies() { Get.put(MainController()); } }调用Get.put()方法我们就注入了controller之后我们可以直接在视图层拿到这个controller。import package:flutter/material.dart; import package:flutter_mvvm_demo/home_controller.dart; import package:get/get.dart; class HomeView extends GetViewHomeController { const HomeView({super.key}); override Widget build(BuildContext context) { return Center( child: ElevatedButton(onPressed: () { Get.toNamed(/main); }, child: const Text(跳转主界面)) , ); } }import package:flutter/material.dart; import package:flutter_mvvm_demo/main_controller.dart; import package:get/get.dart; class MainView extends GetViewMainController { const MainView({super.key}); override Widget build(BuildContext context) { return Obx(() Row(children: [ Text(${controller.count}), ElevatedButton(onPressed: () { controller.plus(); }, child: const Text()) ])); } }视图层我们直接继承GetView比较方便这样可以直接拿到之前注入的controller。使用Obx括起来的内容当被观察的属性值被修改时直接更新Obx里面的界面。我们再来看一看怎么定义可以被观察的属性类似于原生开发中ObservableField这样的。import package:get/get.dart; class MainController extends GetxController { var count 0.obs; plus() count; }你没有看错直接在属性值的地方加一个.obs就可以了。这样count的值一旦被修改就会通知刷新Obs括起来的界面。作者dora链接https://juejin.cn/post/7200775196113895483最后如果想要成为架构师或想突破20~30K薪资范畴那就不要局限在编码业务要会选型、扩展提升编程思维。此外良好的职业规划也很重要学习的习惯很重要但是最重要的还是要能持之以恒任何不能坚持落实的计划都是空谈。如果你没有方向这里给大家分享一套由阿里高级架构师编写的《Android八大模块进阶笔记》帮大家将杂乱、零散、碎片化的知识进行体系化的整理让大家系统而高效地掌握Android开发的各个知识点。相对于我们平时看的碎片化内容这份笔记的知识点更系统化更容易理解和记忆是严格按照知识体系编排的。全套视频资料一、面试合集二、源码解析合集三、开源框架合集欢迎大家一键三连支持若需要文中资料直接点击文末CSDN官方认证微信卡片免费领取↓↓↓

相关新闻

项目开发使用教程和常见问题和解决方法(cuda cudnn安装教程)

项目开发使用教程和常见问题和解决方法(cuda cudnn安装教程)

项目开发使用教程和常见问题和解决方法 目录 项目开发使用教程和常见问题和解决方法 一、Python开发环境搭建 1. 安装cuda cudnn(深度学习入门必装) (1)Windows安装方法 (2)Ubuntu18.04安装方法 2. 安装Python(推荐使用Anaconda) (1)Windows安装…

2026/8/27 12:40:05 阅读更多 →
2026全国正规手表维修网点怎么选?认准官方授权更安心

2026全国正规手表维修网点怎么选?认准官方授权更安心

正规手表维修网点核心核验标准腕表属于精密机械类配饰,日常使用中难免出现走时误差、磕碰损伤、部件老化等问题,不少用户在选择维修机构时会遇到无从判断正规性的困扰,轻则遭遇乱收费,重则导致腕表不可逆损伤、丧失品牌原有保修权…

2026/8/27 12:40:05 阅读更多 →
移动设备电量计IC选型与调试指南:从SOC估算原理到实战避坑

移动设备电量计IC选型与调试指南:从SOC估算原理到实战避坑

前阵子帮一位朋友评估运动手环的电池方案,对方第一句话就问:“你那边有没有电量估算特别准的方案?现在这块表电量显示到20%就突然关机,用户投诉多得处理不过来。”——这种问题我太熟悉了。移动和便携式设备越做越薄、功能越堆越多…

2026/8/27 12:39:05 阅读更多 →

最新新闻

基于RWKV的中文网文生成实战:从模型原理到LoRA微调

基于RWKV的中文网文生成实战:从模型原理到LoRA微调

简介:在自然语言处理与AI写作工具快速演进的今天,生成式模型的长文本建模能力成为核心议题。传统Transformer架构的自注意力机制虽在语义理解上表现出色,却受限于平方级计算复杂度,难以支撑小说、网文等超长文本的高效生成。RWKV作…

2026/8/27 13:27:52 阅读更多 →
解密prompt系列26. 人类思考vs模型思考:抽象和发散思维

解密prompt系列26. 人类思考vs模型思考:抽象和发散思维

前言 在Chain of Thought出来后,出现过许多的优化方案例如Tree of thought, Graph of Thought, Algorithm of Thought等等,不过这些优化的出发点都更加"Machine Like",而非"Human Like", 哈哈不是说机器化不好,仅仅是对A…

2026/8/27 13:27:52 阅读更多 →
Physical AI经验工程:构建机器人全链路数据基建的实践指南

Physical AI经验工程:构建机器人全链路数据基建的实践指南

之前在机器人项目里做数据闭环时,最头疼的不是模型训练,而是“经验”本身很难被采集、标注、回放和复用。同一个搬运动作,老师傅做出来是丝滑的,模型学出来却是抖动的;同样的导航策略,仿真环境里跑得很好&a…

2026/8/27 13:27:52 阅读更多 →
工业级仓储目标检测数据集:托盘与箱体联合识别实战指南

工业级仓储目标检测数据集:托盘与箱体联合识别实战指南

简介:目标检测是计算机视觉落地工业场景的核心技术,其原理在于定位与分类图像中特定物体,关键价值在于支撑实时决策与自动化执行。在智能仓储领域,托盘与箱体作为两类强耦合但语义独立的关键目标,其精准识别直接决定AG…

2026/8/27 13:27:52 阅读更多 →
免安装LabelImg工具:VOC/YOLO格式标注与计算机视觉数据集构建实战

免安装LabelImg工具:VOC/YOLO格式标注与计算机视觉数据集构建实战

简介:在计算机视觉领域,高质量的数据标注是模型训练成功的基石。目标检测作为核心任务,其标注数据需要精确的边界框和类别信息。PASCAL VOC和YOLO是两种主流的标注格式,分别采用XML结构化存储和归一化坐标文本存储,服务…

2026/8/27 13:27:52 阅读更多 →
数学建模竞赛解题心法:从问题分析到模型构建与论文写作

数学建模竞赛解题心法:从问题分析到模型构建与论文写作

1. 项目概述:从赛题到解题的思维跃迁又到了一年一度的MathorCup高校数学建模挑战赛,作为一项在国内高校圈子里颇具分量的赛事,每年都能吸引大量数学、计算机、经管等专业的同学参与。今年的D题,从题目上看,延续了Matho…

2026/8/27 13:26:51 阅读更多 →

日新闻

Go语言构建企业级AI服务网关:统一管理英伟达等AI接口调用

Go语言构建企业级AI服务网关:统一管理英伟达等AI接口调用

1. 项目概述:从零构建一个企业级的AI服务网关 最近在帮一个做内容审核的团队做技术架构升级,他们原来的业务里,每天有几十万张图片和短视频需要过审,最初是接了几个开源的AI模型自己部署,但效果和性能一直不太稳定。后…

2026/8/27 0:00:51 阅读更多 →
网盘直链下载助手5分钟解析八大网盘真实地址

网盘直链下载助手5分钟解析八大网盘真实地址

网盘直链下载助手5分钟解析八大网盘真实地址 【免费下载链接】Online-disk-direct-link-download-assistant 一个基于 JavaScript 的网盘文件下载地址获取工具。基于【网盘直链下载助手】修改 ,支持 百度网盘 / 阿里云盘 / 中国移动云盘 / 天翼云盘 / 迅雷云盘 / 夸…

2026/8/27 1:06:27 阅读更多 →
从零点亮 ESP32:Arduino ESP32 开发环境搭建与首次烧录完整指南

从零点亮 ESP32:Arduino ESP32 开发环境搭建与首次烧录完整指南

从零点亮 ESP32:Arduino ESP32 开发环境搭建与首次烧录完整指南 【免费下载链接】arduino-esp32 Arduino core for the ESP32 family of SoCs 项目地址: https://gitcode.com/GitHub_Trending/ar/arduino-esp32 Arduino ESP32 是乐鑫官方的 ESP32 系列 Ardui…

2026/8/27 1:06:27 阅读更多 →

周新闻

[光学原理与应用-521]:对光的错误理解与纠偏

[光学原理与应用-521]:对光的错误理解与纠偏

首先光是一种能量的载体和形态,宏观上观察到的光是由无数个微观的光量子组成的,每个光子在产生的瞬间,其在真空的空间中以确定不变的速度沿着一个初始的方向一直向前,在微观层面,每个光量子的运动轨迹是以波函数所展现…

2026/8/26 14:45:33 阅读更多 →
SIP通话转接原理与REFER方法实战解析

SIP通话转接原理与REFER方法实战解析

1. 通话转接不是“挂断再拨号”,而是SIP会话的动态重定向你有没有遇到过这样的场景:客服坐席A正在和客户通电话,突然需要把这通对话无缝转给专家坐席B,客户完全感知不到中间的断连——既没听到忙音,也没被要求重新拨号…

2026/8/26 17:46:43 阅读更多 →
Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

Kolla-ansible单节点OpenStack部署实战:从环境准备到排坑指南

1. 为什么选择Kolla-ansible来部署单节点OpenStack?如果你正在寻找一种能把OpenStack从“概念”快速变成“可用的实验环境”的方法,那么Kolla-ansible几乎是当前最主流、最省心的选择。我见过太多人卡在手动编译依赖、配置服务、处理版本冲突的泥潭里&am…

2026/8/26 14:46:37 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/26 3:50:20 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/26 17:46:39 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/26 1:24:05 阅读更多 →