Flutter 3.19 桌面应用开发:窗口大小适配与菜单栏自定义
一、窗口大小适配方案
在 Windows/macOS 桌面应用中,需通过 dart:io 和 platform_dispatcher 控制窗口属性:
- 设置初始窗口尺寸
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());
}
- 动态响应窗口变化
dart
class ResponsiveLayout extends StatelessWidget {
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) {
// 根据窗口宽度调整布局
if (constraints.maxWidth > 1000) {
return _buildWideLayout();
} else {
return _buildCompactLayout();
}
},
);
}
}
- 全屏/退出全屏控制
dart
// 进入全屏
PlatformDispatcher.instance.platformViewsController.enterFullscreen();
// 退出全屏
PlatformDispatcher.instance.platformViewsController.exitFullscreen();
二、菜单栏自定义实现
使用 PlatformMenuBar 和 PlatformMenuItem 创建原生风格菜单:
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') |
四、最佳实践建议
-
响应式设计原则
- 使用 $$ \text{MediaQuery.of(context).size} $$ 获取实时尺寸
- 通过 $$ \text{constraints.maxWidth} $$ 实现断点布局
-
菜单状态管理
dartValueNotifier<bool> isSaveEnabled = ValueNotifier(false); PlatformMenuItem( label: '保存', enabled: isSaveEnabled, onSelected: _saveFile, ) -
平台特性检测
dartvoid _handleFullscreen() { if (Platform.isMacOS) { // macOS特殊处理 } else { // Windows/Linux处理 } }
注意事项:
- 使用
flutter pub add platform_menu_bar安装最新菜单插件- 在
pubspec.yaml中设置最小版本:
yamlenvironment: sdk: ">=3.0.0 <4.0.0" flutter: ">=3.19.0"