flutter3-macOS桌面端os系统|flutter3.x+window_manager仿mac桌面管理

原创力作flutter3+getX+window_manager仿Mac桌面系统平台Flutter-MacOS

flutter3_macui基于最新跨端技术flutter3.19+dart3.3+window_manager+system_tray构建的一款桌面端仿MacOS风格os系统项目。支持自定义主题换肤、毛玻璃虚化背景、程序坞Dock菜单多级嵌套+自由拖拽排序、可拖拽路由弹窗等功能。

flutter3-macOS桌面端os系统|flutter3.x+window_manager仿mac桌面管理

FlutterMacOS系统是自研原创多级菜单、支持可拖拽弹窗打开路由页面模板。

flutter3-macOS桌面端os系统|flutter3.x+window_manager仿mac桌面管理

使用技术

  • 编辑器: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

flutter3-macOS桌面端os系统|flutter3.x+window_manager仿mac桌面管理

flutter3-macOS桌面端os系统|flutter3.x+window_manager仿mac桌面管理

功能特色

  1. 桌面菜单支持JSON配置/二级弹窗菜单
  2. 采用ios虚化毛玻璃背景效果
  3. 经典程序坞Dock菜单
  4. 程序坞Dock菜单可拖拽式排序、支持二级弹窗式菜单
  5. 丰富视觉效果,自定义桌面主题换肤背景
  6. 可视化多窗口路由,支持弹窗方式打开新路由页面
  7. 自定义路由弹窗支持全屏、自由拖拽
  8. 支持macOS和windows 11两种风格Dock菜单

flutter3-macOS桌面端os系统|flutter3.x+window_manager仿mac桌面管理

项目结构

flutter3-macOS桌面端os系统|flutter3.x+window_manager仿mac桌面管理

通过 flutter create flutter_macos 命令即可快速创建一个flutter空项目模板。

通过 flutter run -d windows 命令即可运行到windows桌面。

flutter3-macOS桌面端os系统|flutter3.x+window_manager仿mac桌面管理

在开始开发项目之前,需要自己配置好flutter sdk开发环境。具体配置大家可以去官网查阅资料,有详细的配置步骤。

flutter3-macOS桌面端os系统|flutter3.x+window_manager仿mac桌面管理

flutter3-macOS桌面端os系统|flutter3.x+window_manager仿mac桌面管理

flutter3-macOS桌面端os系统|flutter3.x+window_manager仿mac桌面管理

flutter3-macOS桌面端os系统|flutter3.x+window_manager仿mac桌面管理

flutter3-macOS桌面端os系统|flutter3.x+window_manager仿mac桌面管理

flutter3-macOS桌面端os系统|flutter3.x+window_manager仿mac桌面管理

flutter3-macOS桌面端os系统|flutter3.x+window_manager仿mac桌面管理

flutter3-macOS桌面端os系统|flutter3.x+window_manager仿mac桌面管理

flutter3-macOS桌面端os系统|flutter3.x+window_manager仿mac桌面管理

flutter3-macOS桌面端os系统|flutter3.x+window_manager仿mac桌面管理

flutter3-macOS桌面端os系统|flutter3.x+window_manager仿mac桌面管理

flutter3-macOS桌面端os系统|flutter3.x+window_manager仿mac桌面管理

flutter3-macOS桌面端os系统|flutter3.x+window_manager仿mac桌面管理

flutter3-macOS桌面端os系统|flutter3.x+window_manager仿mac桌面管理

flutter3-macOS桌面端os系统|flutter3.x+window_manager仿mac桌面管理

Flutter3桌面os布局模板

桌面os布局整体分为顶部导航条+桌面菜单+底部Dock菜单三大模块。

flutter3-macOS桌面端os系统|flutter3.x+window_manager仿mac桌面管理

return Scaffold(   key: scaffoldKey,   body: Container(     // 背景图主题     decoration: skinTheme(),     // DragToResizeArea自定义缩放窗口     child: DragToResizeArea(       child: Flex(         direction: Axis.vertical,         crossAxisAlignment: CrossAxisAlignment.start,         children: [           // 导航栏           WindowTitlebar(             onDrawer: () {               // 自定义打开右侧drawer               scaffoldKey.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(),   ), );

Flutter3实现程序坞Dock菜单

flutter3-macOS桌面端os系统|flutter3.x+window_manager仿mac桌面管理

flutter3-macOS桌面端os系统|flutter3.x+window_manager仿mac桌面管理

底部Dock菜单支持macOSwindows11两种风格。采用毛玻璃虚化背景、支持拖拽排序二级弹窗菜单

flutter3-macOS桌面端os系统|flutter3.x+window_manager仿mac桌面管理

鼠标滑过图标,该图标带动画效果放大,采用 MouseRegion 和 ScaleTransition 缩放动画组件一起实现功能。

// 动画控制器 late AnimationController controller = AnimationController(duration: const Duration(milliseconds: 300), vsync: this);

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),                     ),                   ),                 ),               ),             ),           ],         ),       ),     ),   ), )

菜单JSON格式配置项,图标支持Icon图标Image图片

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'}, ];

flutter3-macOS桌面端os系统|flutter3.x+window_manager仿mac桌面管理

二级菜单采用showDialog组件实现三列排版,支持背景虚化、可滚动列表。定位采用Positioned组件实现功能。

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: () {                                   // ...                                 },                               ),                             );                           }),                         ),                       ),                     ],                   ),                 ),               ),             ),           ),         ],       );     },   ); }

Flutter实现桌面多级菜单

flutter3-macOS桌面端os系统|flutter3.x+window_manager仿mac桌面管理

flutter3-macOS桌面端os系统|flutter3.x+window_manager仿mac桌面管理

桌面菜单采用 Wrap 组件竖向排列显示。

@override 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(               ...             ),           ),         );       }),     ),   ); }

桌面菜单缩略二级弹窗菜单和Dock菜单实现思路差不多。点击桌面菜单通过弹窗方式显示配置的页面。

/**   桌面弹窗式路由页面  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配置和Dock菜单配置差不多,只不过多了componentdialog两个参数。component参数是弹窗打开需要显示的页面,dialog是自定义弹窗配置参数。

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,     }   }, ];

flutter3-macOS桌面端os系统|flutter3.x+window_manager仿mac桌面管理

好了,综上就是flutter3+window_manager实战桌面端仿MacOS系统的一些分享,希望对大家有所帮助!

附上最近两个实例项目

https://www.cnblogs.com/xiaoyan2017/p/17938517

https://www.cnblogs.com/xiaoyan2017/p/18048244

flutter3-macOS桌面端os系统|flutter3.x+window_manager仿mac桌面管理

 

发表评论

评论已关闭。

相关文章