【Flutter】Getx设计模式及Provider、Repository、Controller、View等

本文基于Getx 4,x 本本

1、引入

再次接触到Flutter项目,社区俨然很完善和活跃。pubs.dev 寻找状态管理的时候看到很熟悉的Getx时间,俨然发现Getx的版本已到是4.x版本,看到Getx的功能已经非常强大了,庞大的API俨然成为一种开发框架,关于API不是本文介绍的目的。我们就去繁从简,看看从框架层次,作者想传递给我们什么开发思想呢。

2、官方示例

2.1示例结构

Get示例图

2.2 目录结构

目录结构

2.3 总结

移动端 或者前端很少去直接操作远程数据, 故不存在类似Spring 中的DAO, 此处示例中抽象出的Provider 我们可以理解为服务提供者即此处的网络请求Service,亦或者DBService的上层服务提供者。

provider

2.3.1 Repository

关于上述的Provider 层, 从2.1中我们看到了,还有一层Repository,那我们就开始唠唠这个Repository设计模式。 JJ关于此处Repository 模式大概有以下几点。

  • 简化业务层(Controller)的数据处理逻辑DTO

可能有人会说了,Provider层已经将Json转换成Model 了,那这里怎么提效呢。Model 能可能并不完全是前端展现的Entity,比如Model 中含有JsonString

  • 提高测试性
    便于Mock仓储对象,来模拟数据访问想过
  • 数据隔离的作用
    这个是我YY的,原始数据的immutable。

2.3.2 Controller

关于Controller, 从2.1 中我们看到了GetxController混淆的两个协议,主要是生命周期的监听。此处GetxContorller 不展开讲。

2.3.3 View

getx 有个与之对应的GetView, 可以帮我们注入对应的Controller。此处需要注意的是,如果该View有多个Controller管理,那还是采用Get.put Get.lazyPut, Get.creat来注入实例。

2.3.4 Bindings


class HomeBindings extends Bindings {void dependencies() {}
}

通过Get.LazyPut 来注入实例。依次为Provider. -> Reposity -> Contorller, 需要注意的是如果在首页用到Binding initialBinding, 需要实例话。

3、JJ的示例

看到这里就没必要在看下去了,自己可以造个轮子。这里只是为了记录一下。

3.1 Presentation

3.1.1 View
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:xun_dian_ft/global_widgets/tabbar/presentation/controller/tabbar_controller.dart';
import 'package:xun_dian_ft/pages/home/presentation/view/mine_view.dart';
import 'package:xun_dian_ft/pages/home/presentation/view/notice_View.dart';
import 'package:xun_dian_ft/pages/home/presentation/view/process_view.dart';
import 'package:xun_dian_ft/pages/home/presentation/view/wrok_view.dart';/// @brief: 自定义底部导航栏视图
/// @desc: 因iOSer 故定义成和iOS类名
/// @date: 2024-04-05 19:27
/// @author: jeversonjee
class TabbarWidget extends GetView<TabbarController> {final TextStyle normalTextStyle = const TextStyle(color: Colors.grey, fontWeight: FontWeight.w500, fontSize: 12);final TextStyle highlightTextStyle = const TextStyle(color: Colors.red, fontWeight: FontWeight.w700, fontSize: 16);final List<BottomNavigationBarItem> mBarItems = <BottomNavigationBarItem>[BottomNavigationBarItem(label: '工作中心',icon: Image.asset('lib/res/images/tab_work.png',),activeIcon: Image.asset('lib/res/images/tab_work_selected.png',)),BottomNavigationBarItem(label: '巡店进度',icon: Image.asset('lib/res/images/tab_process.png',),activeIcon: Image.asset('lib/res/images/tab_process_selected.png',)),BottomNavigationBarItem(label: '通知公告',icon: Image.asset('lib/res/images/tab_notice.png',),activeIcon: Image.asset('lib/res/images/tab_notice_selected.png',)),BottomNavigationBarItem(label: '我的信息',icon: Image.asset('lib/res/images/tab_mine.png',),activeIcon: Image.asset('lib/res/images/tab_mine_selected.png',))];TabbarWidget({super.key});_renderTabbarItem(BuildContext context, TabbarController ctrl) {return Obx(() => MediaQuery(data: MediaQuery.of(context).copyWith(textScaler: const TextScaler.linear(2.0)),child: BottomNavigationBar(type: BottomNavigationBarType.fixed,showSelectedLabels: true,showUnselectedLabels: true,unselectedItemColor: Colors.grey,selectedItemColor: Colors.blueAccent,selectedLabelStyle: highlightTextStyle,unselectedLabelStyle: normalTextStyle,onTap: ctrl.updateTabIndex,currentIndex: ctrl.tabIndex.value,items: mBarItems,),));}Widget build(BuildContext context) {return SafeArea(child: Scaffold(bottomNavigationBar: _renderTabbarItem(context, controller),body: Obx(() => IndexedStack(index: controller.tabIndex.value,children: [WorkView(), ProcessView(), NoticeView(), MineView()],)),));}
}

3.1.2 Controller

import 'package:get/get.dart';
import 'package:xun_dian_ft/global_widgets/tabbar/data/module_permission_provider.dart';
import 'package:xun_dian_ft/global_widgets/tabbar/data/module_permission_reposity.dart';class TabbarController extends GetxController {TabbarController({required this.reposity});final IModulePermisionReposity reposity;var tabIndex = 0.obs;void updateTabIndex(int currentIdx) {tabIndex.value = currentIdx;List<Module> values = Module.values;reposity.getAccessPermissionBy(values[currentIdx]);}void onInit() {}void dispose() {super.dispose();}
}

3.2 Data

3.2.1 Provider
import 'package:get/get.dart';
import 'package:xun_dian_ft/core/network/base_provider.dart';enum Module {work(description: '工作中心', checkName: 'Android工作中心'),process(description: '巡店进度', checkName: 'Android巡店进度'),notice(description: '通知公告', checkName: 'Android通知公告'),mine(description: '我的信息', checkName: 'Android我的信息');const Module({required this.description, required this.checkName});final String description;final String checkName;
}/// @desc: 关于Provider即为上层数据操作层面,个人认为和Service相似.可以理解为imuatbleSorceData
/// @date:2024-04-06
/// @author: jeversonjee
abstract class IModulePermissionProvider {Future<bool> accessToThisModule(Module module);
}class ModulePermissionProvider extends BaseProvider implements IModulePermissionProvider {Future<bool> accessToThisModule(Module module) async {/// TODO: 实现相应的网络查询接口return Future(() => true);}
}

3.2.2 Reposity

import 'package:xun_dian_ft/global_widgets/tabbar/data/module_permission_provider.dart';abstract class IModulePermisionReposity {Future<bool> getAccessPermissionBy(Module module);
}class ModulePersionReposity implements IModulePermisionReposity {ModulePersionReposity({required this.provider});final IModulePermissionProvider provider;Future<bool> getAccessPermissionBy(Module module) {return provider.accessToThisModule(module);}
}
```### 3.2.3 Bindings
````dart
import 'package:get/get.dart';
import 'package:xun_dian_ft/global_widgets/tabbar/data/module_permission_provider.dart';
import 'package:xun_dian_ft/global_widgets/tabbar/data/module_permission_reposity.dart';
import 'package:xun_dian_ft/global_widgets/tabbar/presentation/controller/tabbar_controller.dart';class ModulePermissionBinding implements Bindings {void dependencies() {Get.lazyPut<IModulePermissionProvider>(() => ModulePermissionProvider());Get.lazyPut<IModulePermisionReposity>(() => ModulePersionReposity(provider: Get.find<IModulePermissionProvider>()));Get.lazyPut<TabbarController>(() => TabbarController(reposity: Get.find()));}
}
```

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/299425.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Windows Server 2008添加Web服务器(IIS)、WebDAV服务、网络负载均衡

一、Windows Server 2008添加Web服务器&#xff08;IIS&#xff09; &#xff08;1&#xff09;添加角色&#xff0c;搭建web服务器&#xff08;IIS&#xff09; &#xff08;2&#xff09;添加网站&#xff0c;关闭默认网页&#xff0c;添加默认文档 在客户端浏览器输入服务器…

蓝桥杯 十一届C++A组 字符排序 21分(运行超时)

思路&#xff1a; 1. 此题考查的冒泡排序中的交换次数&#xff0c;其实就是考察当前数与后面的逆序对个数问题。而为了最大利用位数&#xff0c;应当使每一位都不小于后面的字符&#xff0c;否则会造成一次逆序对的浪费&#xff08;贪心&#xff0c;为了使总位数最少&#xff…

每日OJ题_优先级队列_堆③_力扣692. 前K个高频单词

目录 力扣692. 前K个高频单词 解析代码 力扣692. 前K个高频单词 692. 前K个高频单词 难度 中等 给定一个单词列表 words 和一个整数 k &#xff0c;返回前 k 个出现次数最多的单词。 返回的答案应该按单词出现频率由高到低排序。如果不同的单词有相同出现频率&#xff0c…

《QT实用小工具·三》偏3D风格的异型窗体

1、概述 源码放在文章末尾 可以在窗体中点击鼠标左键进行图片切换&#xff0c;项目提供了一些图片素材&#xff0c;整体风格偏向于3D类型&#xff0c;也可以根据需求自己放置不同的图片。 下面是demo演示&#xff1a; 项目部分代码如下所示&#xff1a; 头文件部分&#xff…

基于SSM+Vue的服装商城系统

绪论 项目研究的背景 困扰管理层的许多问题当中,服装定制将是广大用户们不可忽视的一块。但是管理好服装定制又面临很多麻烦需要解决,例如,如何在工作琐碎,记录繁多的情况下将服装定制的当前情况反应给相关管理人员决策,等等。在此情况下开发一款服装定制系统&#xff0c;于是…

DataLoader的使用

DataLoader的使用 测试DataLoader&#xff0c;batch_size大小为4 import torchvision.datasets from torch.utils.data import DataLoadertest_data torchvision.datasets.CIFAR10("./dataset", trainFalse, transformtorchvision.transforms.ToTensor()) test_loa…

215 基于matlab的快速跟踪算法

基于matlab的快速跟踪算法&#xff0c;提出一种简单又快速、 鲁棒性的算法&#xff0c;基于贝叶斯框架下&#xff0c;该模型 &#xff08;即图像强度和从目标位置&#xff09; 的低级功能及周边地区的统计相关性的时空关系。跟踪问题是通过计算信心地图&#xff0c;并将以最大限…

闪站侠洗护管理系统,洗衣洗鞋小程序软件定制,干洗连锁店软件系统搭建;

闪站侠洗护管理系统&#xff0c;洗衣洗鞋小程序软件定制&#xff0c;干洗连锁店软件系统搭建&#xff1b; 为了让每一个洗衣洗鞋工厂与门店的连接更加高效便捷&#xff0c;送洗流程更加简单轻松&#xff0c;拽牛科技倾心打造洗衣洗鞋管理软件。我们的目标是通过高效和优质的服务…

Navicat Premium工具安装教程(超详细讲解)

Navicat Premium是一款功能强大并可支持多连接的数据库管理工具&#xff0c;它允许在单一程序中同时连接多达7种数据库&#xff0c;包括MySQL、MariaDB、MongoDB、SQL server、SQLite、Oracle和PostgreSQl数据库&#xff0c;让管理不同类型的数据库更加快速便捷。 安装Navicat…

隐私计算实训营学习九:隐语多方安全计算在安全核对的行业实践

文章目录 一、业务背景&#xff1a;安全核对产生的土壤二、产品方案&#xff1a;从试点到规模化的路三、技术共建&#xff1a;与隐语的共同成长 一、业务背景&#xff1a;安全核对产生的土壤 业务背景&#xff1a;很多粗放使用数据的方式被新出台的法律法规所规范&#xff0c;…

Redis的I/O多路复用

Redis是单线程的&#xff0c;为什么还那么快&#xff1f; 1.redis是基于内存的 2.redis使用I/O多路复用模型 关于I/O多路复用&#xff1a; 多路&#xff1a;多个客户端连接复用&#xff1a;使用单线程就能够实现同时处理多个客户端的连接 单线程去监控多个Socket&#xff…

数据库的简单查询

一、检索一列或多列1.检索单独一列 select 列名 from 表名; select order_num from orders; 2.检索多列数据 select 列 1&#xff0c;列 2... from 表名; select order_num,order_date from orders; select order_date,order_num from orders; 3.查询所有字段 select * from…

SQL注入---POST注入

文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 一. POST提交概述 在Webshell文章中介绍过post提交和get提交的区别&#xff0c;这里不再赘述 post提交和get提交的区别&#xff1a; get方式提交URL中的参数信息&#xff0c;post方式则是将信…

博客部署001-centos安装docker

1、安装docker 1.1 卸载旧版本的 Docker sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine1.2 设置 Docker 仓库 安装 Docker Engine 之前&#xff0c;首先需要设置…

幕译--本地字幕生成与翻译--Whisper客户端

幕译–本地字幕生成与翻译–Whisper客户端 本地离线的字幕生成与翻译&#xff0c;支持显卡加速。可免费试用&#xff0c;无次数限制 基于Whisper&#xff0c;希望做最好的Whisper客户端 功能介绍 本地离线&#xff0c;不用担心隐私问题支持显卡&#xff08;CUDA&#xff09;…

重读Java设计模式: 适配器模式解析

引言 在软件开发中&#xff0c;经常会遇到不同接口之间的兼容性问题。当需要使用一个已有的类&#xff0c;但其接口与我们所需的不兼容时&#xff0c;我们可以通过适配器模式来解决这一问题。适配器模式是一种结构型设计模式&#xff0c;它允许接口不兼容的类之间进行合作。本…

C++设计模式:装饰器模式(四)

1、定义与动机 装饰器模式定义&#xff1a;动态&#xff08;组合&#xff09;地给一个对象增加一些额外的职责。就增加功能而言&#xff0c;Decorator模式比生成子类&#xff08;继承&#xff09;更为灵活&#xff08;消除重复代码 & 减少子类个数&#xff09;。 在某些情…

c++的STL(8) -- queue

queue容器概述 queue容器实现了实现了和队列相同结构的容器。 如图&#xff0c;队列这种结构有两端: 队首和队尾。 对于队列&#xff0c;我们添加数据只能从队尾添加&#xff0c;删除数据只能从队首删除。是一种先进先出的结构。 -- 当然读取数据也只能从队首或者队尾读取。…

Python TensorFlow 2.6 获取 MNIST 数据

Python TensorFlow 2.6 获取 MNIST 数据 2 Python TensorFlow 2.6 获取 MNIST 数据1.1 获取 MNIST 数据1.2 检查 MNIST 数据 2 Python 将npz数据保存为txt3 Java 获取数据并使用SVM训练4 Python 测试SVM准确度 2 Python TensorFlow 2.6 获取 MNIST 数据 1.1 获取 MNIST 数据 …

【数据结构】考研真题攻克与重点知识点剖析 - 第 3 篇:栈、队列和数组

前言 本文基础知识部分来自于b站&#xff1a;分享笔记的好人儿的思维导图与王道考研课程&#xff0c;感谢大佬的开源精神&#xff0c;习题来自老师划的重点以及考研真题。此前我尝试了完全使用Python或是结合大语言模型对考研真题进行数据清洗与可视化分析&#xff0c;本人技术…