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

2024-04-13 11:04

本文主要是介绍基于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

在这里插入图片描述

这篇关于基于flutter3.x+window_manager+getx桌面端仿macOS系统的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/899955

相关文章

CSS3 最强二维布局系统之Grid 网格布局

《CSS3最强二维布局系统之Grid网格布局》CS3的Grid网格布局是目前最强的二维布局系统,可以同时对列和行进行处理,将网页划分成一个个网格,可以任意组合不同的网格,做出各种各样的布局,本文介... 深入学习 css3 目前最强大的布局系统 Grid 网格布局Grid 网格布局的基本认识Grid 网

在不同系统间迁移Python程序的方法与教程

《在不同系统间迁移Python程序的方法与教程》本文介绍了几种将Windows上编写的Python程序迁移到Linux服务器上的方法,包括使用虚拟环境和依赖冻结、容器化技术(如Docker)、使用An... 目录使用虚拟环境和依赖冻结1. 创建虚拟环境2. 冻结依赖使用容器化技术(如 docker)1. 创

CentOS系统Maven安装教程分享

《CentOS系统Maven安装教程分享》本文介绍了如何在CentOS系统中安装Maven,并提供了一个简单的实际应用案例,安装Maven需要先安装Java和设置环境变量,Maven可以自动管理项目的... 目录准备工作下载并安装Maven常见问题及解决方法实际应用案例总结Maven是一个流行的项目管理工具

C#实现系统信息监控与获取功能

《C#实现系统信息监控与获取功能》在C#开发的众多应用场景中,获取系统信息以及监控用户操作有着广泛的用途,比如在系统性能优化工具中,需要实时读取CPU、GPU资源信息,本文将详细介绍如何使用C#来实现... 目录前言一、C# 监控键盘1. 原理与实现思路2. 代码实现二、读取 CPU、GPU 资源信息1.

Window Server创建2台服务器的故障转移群集的图文教程

《WindowServer创建2台服务器的故障转移群集的图文教程》本文主要介绍了在WindowsServer系统上创建一个包含两台成员服务器的故障转移群集,文中通过图文示例介绍的非常详细,对大家的... 目录一、 准备条件二、在ServerB安装故障转移群集三、在ServerC安装故障转移群集,操作与Ser

在C#中获取端口号与系统信息的高效实践

《在C#中获取端口号与系统信息的高效实践》在现代软件开发中,尤其是系统管理、运维、监控和性能优化等场景中,了解计算机硬件和网络的状态至关重要,C#作为一种广泛应用的编程语言,提供了丰富的API来帮助开... 目录引言1. 获取端口号信息1.1 获取活动的 TCP 和 UDP 连接说明:应用场景:2. 获取硬

Window Server2016加入AD域的方法步骤

《WindowServer2016加入AD域的方法步骤》:本文主要介绍WindowServer2016加入AD域的方法步骤,包括配置DNS、检测ping通、更改计算机域、输入账号密码、重启服务... 目录一、 准备条件二、配置ServerB加入ServerA的AD域(test.ly)三、查看加入AD域后的变

Window Server2016 AD域的创建的方法步骤

《WindowServer2016AD域的创建的方法步骤》本文主要介绍了WindowServer2016AD域的创建的方法步骤,文中通过图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价... 目录一、准备条件二、在ServerA服务器中常见AD域管理器:三、创建AD域,域地址为“test.ly”

JAVA系统中Spring Boot应用程序的配置文件application.yml使用详解

《JAVA系统中SpringBoot应用程序的配置文件application.yml使用详解》:本文主要介绍JAVA系统中SpringBoot应用程序的配置文件application.yml的... 目录文件路径文件内容解释1. Server 配置2. Spring 配置3. Logging 配置4. Ma

2.1/5.1和7.1声道系统有什么区别? 音频声道的专业知识科普

《2.1/5.1和7.1声道系统有什么区别?音频声道的专业知识科普》当设置环绕声系统时,会遇到2.1、5.1、7.1、7.1.2、9.1等数字,当一遍又一遍地看到它们时,可能想知道它们是什... 想要把智能电视自带的音响升级成专业级的家庭影院系统吗?那么你将面临一个重要的选择——使用 2.1、5.1 还是