Flutter 3.19 桌面应用开发:适配 Windows/macOS 端窗口大小与菜单栏自定义

Flutter 3.19 桌面应用开发:窗口大小适配与菜单栏自定义

一、窗口大小适配方案

在 Windows/macOS 桌面应用中,需通过 dart:ioplatform_dispatcher 控制窗口属性:

  1. 设置初始窗口尺寸
dart 复制代码
import 'dart:io';
import 'package:flutter/material.dart';

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  
  if (Platform.isWindows || Platform.isMacOS) {
    // 设置初始尺寸(宽度, 高度)
    PlatformDispatcher.instance.platformViewsController
      ..setWindowSize(const Size(1200, 800))
      ..setMinimumWindowSize(const Size(800, 600)); // 最小尺寸限制
  }
  runApp(MyApp());
}
  1. 动态响应窗口变化
dart 复制代码
class ResponsiveLayout extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(
      builder: (context, constraints) {
        // 根据窗口宽度调整布局
        if (constraints.maxWidth > 1000) {
          return _buildWideLayout();
        } else {
          return _buildCompactLayout();
        }
      },
    );
  }
}
  1. 全屏/退出全屏控制
dart 复制代码
// 进入全屏
PlatformDispatcher.instance.platformViewsController.enterFullscreen();

// 退出全屏
PlatformDispatcher.instance.platformViewsController.exitFullscreen();
二、菜单栏自定义实现

使用 PlatformMenuBarPlatformMenuItem 创建原生风格菜单:

dart 复制代码
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

PlatformMenuBar buildAppMenu() {
  return PlatformMenuBar(
    menus: [
      // 文件菜单
      PlatformMenu(
        label: '文件',
        menus: [
          PlatformMenuItem(
            label: '新建',
            shortcut: const SingleActivator(LogicalKeyboardKey.keyN, meta: true),
            onSelected: () => _handleNewFile(),
          ),
          PlatformMenuDivider(),
          PlatformMenuItem(
            label: '退出',
            shortcut: const SingleActivator(LogicalKeyboardKey.keyQ, meta: true),
            onSelected: () => SystemNavigator.pop(),
          ),
        ],
      ),
      
      // 编辑菜单 (macOS需特殊处理)
      if (!Platform.isMacOS) PlatformMenu(
        label: '编辑',
        menus: [
          PlatformMenuItem(
            label: '撤销',
            shortcut: const SingleActivator(LogicalKeyboardKey.keyZ, meta: true),
            onSelected: () => _handleUndo(),
          ),
        ],
      ),
      
      // 帮助菜单
      PlatformMenu(
        label: '帮助',
        menus: [
          PlatformMenuItem(
            label: '关于',
            onSelected: () => _showAboutDialog(),
          ),
        ],
      ),
    ],
  );
}

// 在应用顶层集成
class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: PlatformMenuBar(
        menus: buildAppMenu().menus,
        child: Scaffold(...),
      ),
    );
  }
}
三、跨平台适配要点
特性 Windows 处理 macOS 处理
菜单位置 显示在窗口顶部 自动集成到系统菜单栏
快捷键 Ctrl+Key Cmd+Key
全屏行为 窗口最大化 进入沉浸式全屏
菜单分隔 使用PlatformMenuDivider 需添加key: const ValueKey('div')
四、最佳实践建议
  1. 响应式设计原则

    • 使用 $$ \text{MediaQuery.of(context).size} $$ 获取实时尺寸
    • 通过 $$ \text{constraints.maxWidth} $$ 实现断点布局
  2. 菜单状态管理

    dart 复制代码
    ValueNotifier<bool> isSaveEnabled = ValueNotifier(false);
    
    PlatformMenuItem(
      label: '保存',
      enabled: isSaveEnabled,
      onSelected: _saveFile,
    )
  3. 平台特性检测

    dart 复制代码
    void _handleFullscreen() {
      if (Platform.isMacOS) {
        // macOS特殊处理
      } else {
        // Windows/Linux处理
      }
    }

注意事项

  • 使用 flutter pub add platform_menu_bar 安装最新菜单插件
  • pubspec.yaml 中设置最小版本:
yaml 复制代码
environment:
  sdk: ">=3.0.0 <4.0.0"
  flutter: ">=3.19.0"
相关推荐
火柴就是我1 小时前
让我们实现一个更好看的内部阴影按钮
android·flutter
王晓枫2 小时前
flutter接入三方库运行报错:Error running pod install
前端·flutter
阿白的白日梦10 小时前
winget基础管理---更新/修改源为国内源
windows
shankss10 小时前
Flutter 下拉刷新库 pull_to_refresh_plus 设计与实现分析
flutter
忆江南1 天前
iOS 深度解析
flutter·ios
明君879971 天前
Flutter 实现 AI 聊天页面 —— 记一次 Markdown 数学公式显示的踩坑之旅
前端·flutter
恋猫de小郭1 天前
移动端开发稳了?AI 目前还无法取代客户端开发,小红书的论文告诉你数据
前端·flutter·ai编程
MakeZero1 天前
Flutter那些事-交互式组件
flutter
shankss1 天前
pull_to_refresh_simple
flutter
shankss1 天前
Flutter 下拉刷新库新特性:智能预加载 (enableSmartPreload) 详解
flutter