基于Flutter3.x客户端仿macOS实例macos桌面

#精品长文创作季#

经过大半个月的爆肝式实战输出开发,我的又一心血之作flutter3-macOS项目完结了。

支持自定义主题皮肤背景、整体高斯模糊效果、程序坞Dock菜单多级嵌套+自由拖拽排序、可拖拽路由弹窗等功能。

项目整体分为顶部自定义导航条+桌面菜单区域+底部Dock菜单三大模块。

实现技术

功能性

  1. 桌面菜单垂直自适应排列、JSON配置/二级弹窗菜单
  2. 采用高斯模糊毛玻璃背景效果
  3. 经典程序坞Dock菜单
  4. 程序坞Dock菜单可拖拽式排序、支持二级弹窗式菜单
  5. 丰富视觉效果,自定义桌面主题换肤背景
  6. 可视化多窗口路由,支持弹窗方式打开新路由页面

项目结构目录

通过flutter create flutter_app命令快速创建一个flutter空模板。

通过flutter run -d windows命令运行调试windows桌面。

为了整体效果一致性,flutter_macos项目去掉了系统原生顶部导航条,使用window_manager来进行系统窗口管理。

有下面几个组件是文档没有写的:

return Container(
  height: widget.titlebarHeight,
  decoration: BoxDecoration(
    backgroundBlendMode: widget.backgroundBlendMode,
    color: widget.backgroundColor,
    gradient: widget.gradient,
  ),
  child: Stack(
    children: [
      Row(
        children: [
          // 头部
          Container(
            child: widget.leading,
          ),
          // 可拖动区(标题)
          Expanded(
            child: DragToMoveArea(
              child: SizedBox(
                height: double.infinity,
                child: Row(
                  children: [
                    // 标题(不居中)
                    customTitle(!widget.centerTitle),
                  ],
                ),
              ),
            ),
          ),
          // 尾部
          Container(
            child: widget.trailing,
          ),
          // 按钮组
          WinBtns(theme: widget.actionButtonTheme, buttonSize: widget.actionButtonSize),
        ],
      ),
      // 标题(居中)
      customTitle(widget.centerTitle),
    ],
  ),
);

顶部自定义导航条支持自定义标题(居中)、背景色、头部、尾部、导航条高度等功能。

// 标题
final Widget? title;
// 背景色
final Color? backgroundColor;
// 前景色
final Color? foregroundColor;
// 混合模式
final BlendMode? backgroundBlendMode;
// 渐变背景
final LinearGradient? gradient;
// 标题是否居中
final bool centerTitle;
// 头部
final Widget? leading;
// 尾部
final Widget? trailing;
// 标题栏高度
final double titlebarHeight;
// 右上角按钮组主题色(light/dark)
final String? actionButtonTheme;
// 右上角按钮组宽高
final Size actionButtonSize;

flutter3桌面模板布局

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菜单

flutter-macos项目提供了macoswindows11两种风格dock菜单。

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

flutter-os项目已经正式完结,该项目涉及到的知识点还是蛮多,今天就先分享到这里。

如果大家觉得不错的话,欢迎交流讨论,感谢你的支持~

展开阅读全文

页面更新:2024-04-18

标签:桌面   尾部   缩放   路由   客户端   实例   按钮   菜单   背景   窗口   标题   项目

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2020-2024 All Rights Reserved. Powered By 71396.com 闽ICP备11008920号-4
闽公网安备35020302034903号

Top