基于flutter3.x+window_manager+getx桌面端仿macOS系统

flutter3_macui桌面端仿macOS系统实战项目完结啦!

原创研发flutter3.19+dart3.3+window_manager+getx等技术构建桌面版macOS系统。支持自定义毛玻璃虚化背景、Dock菜单多级嵌套+自由拖拽排序、可拖拽弹窗等功能。

在这里插入图片描述
支持macOS和windows11两种风格。

在这里插入图片描述

使用技术

  • 编辑器:VScode
  • 框架技术:Flutter3.19.2+Dart3.3.0
  • 窗口管理:window_manager^0.3.8
  • 路由/状态管理:get^4.6.6
  • 本地存储:get_storage^2.1.1
  • 拖拽排序:reorderables^0.6.0
  • 图表组件:fl_chart^0.67.0
  • 托盘插件:system_tray^2.0.3

在这里插入图片描述
在这里插入图片描述

特性

  1. 桌面菜单支持二级弹窗菜单
  2. 整体界面虚化毛玻璃模糊效果
  3. 经典Dock菜单
  4. 程序坞Dock菜单可拖拽式排序、支持二级弹窗式菜单
  5. 丰富视觉效果,自定义桌面主题换肤背景
  6. 可视化多窗口路由,支持弹窗方式打开新路由页面

在这里插入图片描述

项目结构

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

flutter-os布局模板

在这里插入图片描述

如上图:整体布局分为顶部导航条+桌面菜单+底部Dock菜单三部分。

return Scaffold(key: scaffoldKey,body: Container(// 背景图主题decoration: skinTheme(),// DragToResizeArea缩放窗口child: DragToResizeArea(child: Flex(direction: Axis.vertical,crossAxisAlignment: CrossAxisAlignment.start,children: [// 导航栏WindowTitlebar(onDrawer: () {// 自定义打开右侧drawerscaffoldKey.currentState?.openEndDrawer();},),// 桌面区域Expanded(child: GestureDetector(child: Container(color: Colors.transparent,child: Row(crossAxisAlignment: CrossAxisAlignment.start,children: [Expanded(child: GestureDetector(child: const WindowDesktop(),onSecondaryTapDown: (TapDownDetails details) {posDX = details.globalPosition.dx;posDY = details.globalPosition.dy;},onSecondaryTap: () {debugPrint('桌面图标右键');showDeskIconContextmenu();},),),],),),onSecondaryTapDown: (TapDownDetails details) {posDX = details.globalPosition.dx;posDY = details.globalPosition.dy;},onSecondaryTap: () {debugPrint('桌面右键');showDeskContextmenu();},),),// Dock菜单settingController.settingData['dock'] == 'windows' ?const WindowTabbar():const WindowDock(),],),),),endDrawer: Drawer(shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(0.0)),width: 300,child: const Settings(),),
);

在这里插入图片描述
在这里插入图片描述

底部Dock菜单滤镜模糊效果,支持macos和windows11两种风格。

在这里插入图片描述

MouseRegion(cursor: SystemMouseCursors.click,onEnter: (event) {setState(() {hoveredIndex = index;});controller.forward(from: 0.0);},onExit: (event) {setState(() {hoveredIndex = -1;});controller.stop();},child: GestureDetector(onTapDown: (TapDownDetails details) {anchorDx = details.globalPosition.dx;},onTap: () {if(item!['children'] != null) {showDockDialog(item!['children']);}},// 缩放动画child: ScaleTransition(alignment: Alignment.bottomCenter,scale: hoveredIndex == index ? controller.drive(Tween(begin: 1.0, end: 1.5).chain(CurveTween(curve: Curves.easeOutCubic))):Tween(begin: 1.0, end: 1.0).animate(controller),child: UnconstrainedBox(child: Stack(alignment: AlignmentDirectional.topCenter,children: [// tooltip提示Visibility(visible: hoveredIndex == index && !draggable,child: Positioned(top: 0,child: SizedOverflowBox(size: Size.zero,child: Container(alignment: Alignment.center,padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 1.0),margin: const EdgeInsets.only(bottom: 20.0),decoration: BoxDecoration(color: Colors.black54,borderRadius: BorderRadius.circular(3.0),),child: Text('${item!['tooltip']}', style: const TextStyle(color: Colors.white, fontSize: 8.0, fontFamily: 'arial')),),),),),// 图片/图标item!['children'] != null ?thumbDock(item!['children']):SizedBox(height: 35.0,width: 35.0,child: item!['type'] != null && item!['type'] == 'icon' ? IconTheme(data: const IconThemeData(color: Colors.white, size: 32.0),child: item!['imgico'],):Image.asset('${item!['imgico']}'),),// 圆点Visibility(visible: item!['active'] != null,child: Positioned(bottom: 0,child: SizedOverflowBox(size: Size.zero,child: Container(margin: const EdgeInsets.only(top: 2.0),height: 4.0,width: 4.0,decoration: BoxDecoration(color: Colors.black87,borderRadius: BorderRadius.circular(10.0),),),),),),],),),),),
)
List dockList = [{'tooltip': 'Flutter3.19', 'imgico': 'assets/images/logo.png'},{'tooltip': 'Safari', 'imgico': 'assets/images/mac/safari.png', 'active': true},{'tooltip': 'Launchpad','imgico': 'assets/images/mac/launchpad.png','children': [{'tooltip': 'Podcasts', 'imgico': 'assets/images/mac/podcasts.png'},{'tooltip': 'Quicktime', 'imgico': 'assets/images/mac/quicktime.png'},{'tooltip': 'Notes', 'imgico': 'assets/images/mac/notes.png'},{'tooltip': 'Reminder', 'imgico': 'assets/images/mac/reminders.png'},{'tooltip': 'Calc', 'imgico': 'assets/images/mac/calculator.png'},]},{'tooltip': 'Appstore', 'imgico': 'assets/images/mac/appstore.png',},{'tooltip': 'Messages', 'imgico': 'assets/images/mac/messages.png', 'active': true},{'type': 'divider'},...{'tooltip': 'Recycle Bin', 'imgico': 'assets/images/mac/bin.png'},
];

在这里插入图片描述
Dock二级菜单采用showDialogPositioned组件实现定位弹窗。

void showDockDialog(data) {anchorDockOffset();showDialog(context: context,barrierColor: Colors.transparent,builder: (context) {return Stack(children: [Positioned(top: anchorDy - 210,left: anchorDx - 120,width: 240.0,height: 210,child: ClipRRect(borderRadius: BorderRadius.circular(16.0),child: BackdropFilter(filter: ImageFilter.blur(sigmaX: 20.0, sigmaY: 20.0),child: Container(padding: const EdgeInsets.symmetric(vertical: 10.0),decoration: const BoxDecoration(backgroundBlendMode: BlendMode.overlay,color: Colors.white,),child: ListView(children: [Container(padding: const EdgeInsets.symmetric(horizontal: 10.0,),child: Wrap(runSpacing: 5.0,spacing: 5.0,children: List.generate(data.length, (index) {final item = data[index];return MouseRegion(cursor: SystemMouseCursors.click,child: GestureDetector(child:  Column(children: [// 图片/图标SizedBox(height: 40.0,width: 40.0,child: item!['type'] != null && item!['type'] == 'icon' ? IconTheme(data: const IconThemeData(color: Colors.black87, size: 35.0),child: item!['imgico'],):Image.asset('${item!['imgico']}'),),SizedBox(width: 70,child: Text(item['tooltip'], style: const TextStyle(color: Colors.black87, fontSize: 12.0), maxLines: 2, overflow: TextOverflow.ellipsis, textAlign: TextAlign.center,),)],),onTap: () {// ...},),);}),),),],),),),),),],);},);
}

flutter3实现桌面菜单

在这里插入图片描述
在这里插入图片描述
桌面菜单使用垂向排列展示。


Widget build(BuildContext context) {return Container(padding: const EdgeInsets.all(10.0),child: Wrap(direction: Axis.vertical,spacing: 5.0,runSpacing: 5.0,children: List.generate(deskList.length, (index) {final item = deskList[index];return MouseRegion(cursor: SystemMouseCursors.click,onEnter: (event) {setState(() {hoveredIndex = index;});},onExit: (event) {setState(() {hoveredIndex = -1;});},child: GestureDetector(onTapDown: (TapDownDetails details) {anchorDx = details.globalPosition.dx;anchorDy = details.globalPosition.dy;},onTap: () {if(item!['children'] != null) {showDeskDialog(item!['children']);}else {showRouteDialog(item);}},child: Container(...),),);}),),);
}

点击桌面图标,采用自定义弹窗组件显示页面内容。

/**桌面弹窗式路由页面  Q:282310962
*/
void showRouteDialog(item) async {// 链接if(item!['link'] != null) {await launchUrl(Uri.parse(item!['link']));return;}// 弹窗图标Widget dialogIcon() {if(item!['type'] != null && item!['type'] == 'icon') {return IconTheme(data: const IconThemeData(size: 16.0),child: item!['imgico'],);}else {return Image.asset('${item!['imgico']}', height: 16.0, width: 16.0, fit: BoxFit.cover);}}// Fdialog参数dynamic dialog = item!['dialog'] ?? {};navigator?.push(FdialogRoute(child: Fdialog(// 标题title: dialog!['title'] ?? Row(children: [dialogIcon(),const SizedBox(width: 5.0,),Text('${item!['title']}',),],),// 内容content: dialog!['content'] ?? ListView(padding: const EdgeInsets.all(10.0),children: [item!['component'] ?? const Center(child: Column(children: [Icon(Icons.layers,), Text('Empty~'),],)),],),titlePadding: dialog!['titlePadding'], // 标题内间距backgroundColor: dialog!['backgroundColor'] ?? Colors.white.withOpacity(.85), // 弹窗背景色barrierColor: dialog!['barrierColor'], // 弹窗遮罩层颜色offset: dialog!['offset'], // 弹窗位置(坐标点)width: dialog!['width'] ?? 800, // 宽度height: dialog!['height'] ?? 500, // 高度radius: dialog!['radius'], // 圆角fullscreen: dialog!['fullscreen'] ?? false, // 是否全屏maximizable: dialog!['maximizable'] ?? true, // 是否显示最大化按钮closable: dialog!['closable'] ?? true, // 是否显示关闭按钮customClose: dialog!['customClose'], // 自定义关闭按钮closeIcon: dialog!['closeIcon'], // 自定义关闭图标actionColor: dialog!['actionColor'], // 右上角按钮组颜色actionSize: dialog!['actionSize'], // 右上角按钮组大小draggable: dialog!['draggable'] ?? true, // 是否可拖拽destroyOnExit: dialog!['destroyOnExit'] ?? false, // 鼠标滑出弹窗是否销毁关闭),));
}

桌面菜单json配置列表。

List deskList = [{'title': 'Flutter3.19', 'imgico': 'assets/images/logo.png', 'link': 'https://flutter.dev/'},{'title': '首页', 'imgico': const Icon(Icons.home_outlined), 'type': 'icon','component': const Home(),'dialog': {'fullscreen': true}},{'title': '工作台', 'imgico': const Icon(Icons.poll_outlined), 'type': 'icon','component': const Dashboard(),},{'title': '组件','imgico': const Icon(Icons.apps),'type': 'icon','children': [{'title': 'Mail', 'imgico': 'assets/images/mac/mail.png'},{'title': 'Info', 'imgico': 'assets/images/mac/info.png'},{'title': 'Editor', 'imgico': 'assets/images/mac/scripteditor.png'},{'title': '下载', 'imgico': const Icon(Icons.download_outlined), 'type': 'icon'},{'title': 'Bug统计', 'imgico': const Icon(Icons.bug_report_outlined), 'type': 'icon'},{'title': '计算器', 'imgico': const Icon(Icons.calculate), 'type': 'icon'},{'title': '图表', 'imgico': const Icon(Icons.bar_chart), 'type': 'icon'},{'title': '打印', 'imgico': const Icon(Icons.print), 'type': 'icon'},{'title': '站内信', 'imgico': const Icon(Icons.campaign), 'type': 'icon'},{'title': '云存储', 'imgico': const Icon(Icons.cloud_outlined), 'type': 'icon'},{'title': '裁剪', 'imgico': const Icon(Icons.crop_outlined), 'type': 'icon'},]},{'title': '私密空间', 'imgico': const Icon(Icons.camera_outlined), 'type': 'icon','component': const Uzone(),},...{'title': '公众号', 'imgico': const Icon(Icons.qr_code), 'type': 'icon','dialog': {'title': const Text('QRcode', style: TextStyle(color: Colors.white60, fontSize: 14.0, fontFamily: 'arial')),'content': Padding(padding: const EdgeInsets.all(10.0),child: Column(mainAxisSize: MainAxisSize.min,children: [Image.asset('assets/images/qrcode_white.png', height: 120.0, fit: BoxFit.contain,),const Spacer(),const Text('扫一扫,关注公众号', style: TextStyle(color: Colors.white60, fontSize: 12.0,),),],),),'backgroundColor': const Color(0xff07c160),'actionColor': Colors.white54,'width': 300,'height': 220,'maximizable': false,'closable': true,'draggable': true,}},
];

在这里插入图片描述
自定义Fdialog弹窗支持如下参数配置

// 标题
final Widget? title;
// 弹窗内容
final Widget content;
// 标题内间距
final EdgeInsetsGeometry? titlePadding;
// 弹窗背景色
final Color? backgroundColor;
// 弹窗遮罩层颜色
final Color? barrierColor;
// 弹窗位置(坐标点)
final Offset? offset;
// 宽度
final num width;
// 高度
final num height;
// 圆角
final double? radius;
// 是否全屏
final bool fullscreen;
// 是否显示最大化按钮
final bool maximizable;
// 是否显示关闭按钮
final bool closable;
// 自定义关闭按钮
final Widget? customClose;
// 自定义关闭图标
final IconData? closeIcon;
// 右上角按钮组颜色
final Color? actionColor;
// 右上角按钮组大小
final double? actionSize;
// 是否可拖拽
final bool draggable;
// 鼠标滑出弹窗是否销毁关闭
final bool destroyOnExit;

Okay,以上就是flutter3+getx开发桌面端os系统的一些分享知识。

https://blog.csdn.net/yanxinyun1990/article/details/136410049

https://blog.csdn.net/yanxinyun1990/article/details/135329724

在这里插入图片描述

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

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

相关文章

前端三剑客 —— JavaScript (第十一节)

内容回顾: jQuery 操作DOM jQuery 事件处理 Ajax jQuery 特效案例 全选效果 tab切换 下拉菜单 自定义动画 Bootstrap 入门 首先我们可以在bootstrap官网上进行下载。官网地址:https//www.bootcss.com/ 首先在我们的页面中导入bootstrap的样式,我们可…

推荐系统综述

推荐系统研究综述 - 中国知网 传统推荐方法主要分类: 1)基于内容推荐方法 主要依据用户与项目之间的特征信息,用户之间的联系不会影响推荐结果,所以不存在冷启动和稀疏问题,但是基于内容推荐的结果新颖程度低并且面临特征提取的问题。 基于内容的推荐方法的思想非…

03-echarts如何画立体柱状图

echarts如何画立体柱状图 一、创建盒子1、创建盒子2、初始化盒子(先绘制一个基本的二维柱状图的样式)1、创建一个初始化图表的方法2、在mounted中调用这个方法3、在方法中写options和绘制图形 二、画图前知识1、坐标2、柱状图图解分析 三、构建方法1、创…

GPT提示词分享 —— 解梦

👉 对你描述的梦境进行解读。 我希望你能充当一个解梦者。我将给你描述我的梦,而你将根据梦中出现的符号和主题提供解释。不要提供关于梦者的个人意见或假设。只提供基于所给信息的事实性解释。 GPT3.5的回答 GPT3.5 👇 感觉有点傻&#xf…

Slf4j+Log4j简单使用

Slf4jLog4j简单使用 文章目录 Slf4jLog4j简单使用一、引入依赖二、配置 log4j2.xml2.1 配置结构2.2 配置文件 三、使用四、使用MDC完成日志ID4.1 程序入口处4.2 配置文件配置打印4.3 多线程日志ID传递配置 五. 官网 一、引入依赖 <dependencies><dependency><g…

大数据建模理论

文章目录 一、数仓概述1、数据仓库概念1.1 概述1.2 数据仓库与数据库的区别1.3 技术选型和架构 2、数仓常见名词2.1 实体2.2 维度2.3 度量2.4 粒度2.5 口径2.6 指标2.7 标签2.8 自然键/持久键/代理键2.9 退化维度2.10 下钻/上卷2.11 数据集市 3、数仓名词之间关系3.1 实体表&am…

Spring 事务失效总结

前言 在使用spring过程中事务是被经常用的&#xff0c;如果不小心或者认识不做&#xff0c;事务可能会失效。下面列举几条 业务代码没有被Spring 容器管理 看下面图片类没有Componet 或者Service 注解。 方法不是public的 Transactional 注解只能用户public上&#xff0c…

李沐41_物体检测和数据集——自学笔记

边缘框 1.一个边缘框可以通过4个数字定义&#xff08;左上xy&#xff0c;右上xy&#xff0c;左下xy&#xff0c;右下xy&#xff09; 2.标注成本高 目标检测数据集 1.每行表示一个物体&#xff08;图片文件名、物体类别、边缘框&#xff09; 2.COCO&#xff1a;80物体、330…

RAG原理详解

什么是RAG 检索增强生成&#xff08;Retrieval Augmented Generation&#xff0c;简称RAG&#xff09;为大型语言模型&#xff08;LLMs&#xff09;提供了从某些数据源检索到的信息&#xff0c;以此作为生成答案的基础。简而言之&#xff0c;RAG是搜索LLM提示的结合&#xff0…

Mac用户必备神器:Default Folder X,让文件操作更快捷、更智能!

Default Folder X for Mac是一款功能强大的文件管理辅助工具&#xff0c;它为Mac用户带来了前所未有的文件操作体验。&#x1f31f; 无论是日常办公、学习还是娱乐&#xff0c;Default Folder X都能帮助你更高效地管理文件&#xff0c;让你的工作更加得心应手。&#x1f4bc; …

AD高速板设计(笔记)

Alt左键高亮某个器件或属性&#xff0c;点击任意位置取消高亮。 TP设置旋转角度为45度&#xff0c;即可选中器件按空格旋转时候每次旋转45度。 先画出想要割槽的区域&#xff0c;选中之后TVB即可开槽。 左右翻转电路板&#xff1a;VB DR打开规则设置 UFO对器件进行扇出&#…

Linux系统部署可视化数据多维表格APITable并实现无公网IP远程协同办公

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-G5XdKx1vxX0o0PES {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

AVM 环视拼接方法介绍

0. 简介 关于车辆的全景环视系统网上已经有很多的资料&#xff0c;然而几乎没有可供参考的代码&#xff0c;这一点对入门的新人来说非常不友好。全景环视系统&#xff0c;又称AVM。在自动驾驶领域&#xff0c;AVM属于自动泊车系统的一部分&#xff0c;是一种实用性极高、可大幅…

面试题总结:HashMap底层原理

不仅仅是一道题&#xff0c;之后的某一天&#xff0c;它可能是破局的关键。 关于HashMap的知识点有哪些呢&#xff1f;分层次展示 1.基础知识&#xff1a; 存储键值对结构、底层数据结构、红黑树和链表 2.位运算与实现 位运算、put、get方法的实现 3.关于锁 segment锁和桶锁、线…

Java 中 Set 集合是如何实现添加元素保证不重复的?

Java 中的 Set 集合是一种不允许包含重复元素的集合。它主要通过两种方式来实现确保元素不重复的机制&#xff1a;一是依赖元素的 hashCode() 方法和 equals() 方法&#xff0c;二是底层数据结构的支持。 1. hashCode() 和 equals() 方法 在 Java 中&#xff0c;每个对象都有…

【服务器配置】docker环境配置

docker环境配置 本文是在ubuntu 22.04机器配置docker环境 查看系统的内核版本 uname -a Linux xxf-ThinkStation-P340 5.15.0-101-generic #111-Ubuntu SMP Tue Mar 5 20:16:58 UTC 2024 x86_64 x86_64 x86_64 GNU/Linuxx86 64位 系统 如果是32位 不能安装docker 更新软件…

分布式数据库Polardb-X架构及特点

PolarDB-X架构 计算节点&#xff08;Compute Node&#xff0c;CN&#xff09;是系统的入口&#xff0c;采用无状态设计的sql引擎提供分布式路由和计算&#xff0c;包括SQL解析器、优化器、执行器等模块。负责数据分布式路由、计算及动态调度&#xff0c;负责分布式事务2PC协调…

基于java+springboot+vue实现的学生信息管理系统(文末源码+Lw+ppt)23-54

摘 要 人类现已进入21世纪&#xff0c;科技日新月异&#xff0c;经济、信息等方面都取得了长足的进步&#xff0c;特别是信息网络技术的飞速发展&#xff0c;对政治、经济、军事、文化等方面都产生了很大的影响。 利用计算机网络的便利&#xff0c;开发一套基于java的大学生…

文献学习-37-动态场景中任意形状针的单目 3D 位姿估计:一种高效的视觉学习和几何建模方法

On the Monocular 3D Pose Estimation for Arbitrary Shaped Needle in Dynamic Scenes: An Efficient Visual Learning and Geometry Modeling Approach Authors: Bin Li,† , Student Member, IEEE, Bo Lu,† , Member, IEEE, Hongbin Lin, Yaxiang Wang, Fangxun Zhong, Me…

PHP01——php快速入门 之 在Mac上使用phpstudy快速搭建PHP环境

PHP01——php快速入门 之 在Mac上使用phpstudy快速搭建PHP环境 0. 前言1. 下载小皮面板1.1 下载phpstudy&#xff08;小皮面板&#xff09;1.2 启动、简单访问1.2.1 启动Apache1.2.2 访问1.2.3 访问自定义文件或页面 2. 创建网站2.1 创建网站2.2 可能遇到的问题2.2.1 hosts权限…