You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Flutter Windows桌面应用中实现全屏切换功能?

Flutter Windows 实现全屏/窗口模式切换(无顶栏底栏)

下面提供两种可行方案,实现类似Chrome F11的全屏切换效果,支持通过图标、弹窗等触发。


方案一:使用 window_manager 第三方包(简单快捷)

这个包封装了Windows窗口操作的常用API,无需自己编写原生代码。

  1. 添加依赖
    在pubspec.yaml中加入:
dependencies:
  window_manager: ^0.3.0

执行flutter pub get完成安装。

  1. 初始化窗口管理
    修改main.dart的main函数,初始化window_manager:
import 'package:flutter/material.dart';
import 'package:window_manager/window_manager.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await windowManager.ensureInitialized();

  // 初始窗口配置
  const windowOptions = WindowOptions(
    title: "全屏切换Demo",
    size: Size(800, 600),
    center: true,
  );

  windowManager.waitUntilReadyToShow(windowOptions, () async {
    await windowManager.show();
    await windowManager.focus();
  });

  runApp(const MyApp());
}
  1. 实现切换逻辑
    在页面的State类中添加状态变量和切换方法:
bool _isFullScreen = false;

Future<void> _toggleFullScreen() async {
  _isFullScreen = !_isFullScreen;
  if (_isFullScreen) {
    // 进入全屏:隐藏标题栏、边框,覆盖整个屏幕
    await windowManager.setFullScreen(true);
    // 可选:隐藏任务栏中的窗口图标
    await windowManager.setSkipTaskbar(true);
  } else {
    // 退出全屏:恢复原窗口状态
    await windowManager.setFullScreen(false);
    await windowManager.setSkipTaskbar(false);
    // 恢复初始窗口大小(可按需调整)
    await windowManager.setSize(const Size(800, 600));
    await windowManager.center();
  }
  setState(() {});
}
  1. 添加触发入口
  • 图标按钮触发:
AppBar(
  title: const Text("全屏切换Demo"),
  actions: [
    IconButton(
      icon: Icon(_isFullScreen ? Icons.fullscreen_exit : Icons.fullscreen),
      onPressed: _toggleFullScreen,
    ),
  ],
)
  • 弹窗触发:
TextButton(
  onPressed: () {
    showDialog(
      context: context,
      builder: (context) => AlertDialog(
        title: const Text("切换全屏模式"),
        content: const Text("确认进入全屏?"),
        actions: [
          TextButton(
            onPressed: () => Navigator.pop(context),
            child: const Text("取消"),
          ),
          TextButton(
            onPressed: () {
              Navigator.pop(context);
              _toggleFullScreen();
            },
            child: const Text("确认"),
          ),
        ],
      ),
    );
  },
  child: const Text("打开全屏切换弹窗"),
)
  1. Windows平台额外配置
    打开windows/runner/main.cpp,添加一行代码绑定窗口句柄:
// ... 原有代码 ...
FlutterWindow window(project);
Win32Window::Point origin(10, 10);
Win32Window::Size size(800, 600);
if (!window.CreateAndShow(L"fullscreen_demo", origin, size)) {
  return EXIT_FAILURE;
}
window.SetQuitOnClose(true);

// 添加这一行
window_manager::WindowManagerPlugin::SetWindow(window.GetHandle());

// ... 原有代码 ...

方案二:原生Windows API调用(无第三方依赖)

如果不想依赖第三方包,可以通过dart:ffi直接调用Windows的user32.dll实现窗口样式修改。

  1. 定义Win32 API绑定
    创建win32_utils.dart文件,写入:
import 'dart:ffi';
import 'dart:io';
import 'package:flutter/foundation.dart';

typedef SetWindowProc = IntPtr Function(IntPtr hwnd, Int32 nIndex, IntPtr dwNewLong);
typedef SetWindow = int Function(int hwnd, int nIndex, int dwNewLong);

typedef GetWindowProc = IntPtr Function(IntPtr hwnd, Int32 nIndex);
typedef GetWindow = int Function(int hwnd, int nIndex);

class Win32 {
  static final DynamicLibrary user32 = Platform.isWindows
      ? DynamicLibrary.open('user32.dll')
      : throw UnsupportedError('仅支持Windows平台');

  static final SetWindow setWindowLongPtr = user32
      .lookupFunction<SetWindowProc, SetWindow>('SetWindowLongPtrW');
  static final GetWindow getWindowLongPtr = user32
      .lookupFunction<GetWindowProc, GetWindow>('GetWindowLongPtrW');

  static const int GWL_STYLE = -16;
  static const int WS_CAPTION = 0x00C00000; // 标题栏样式
  static const int WS_THICKFRAME = 0x00040000; // 可调整边框
  static const int WS_MAXIMIZEBOX = 0x00010000; // 最大化按钮
  static const int WS_MINIMIZEBOX = 0x00020000; // 最小化按钮
}
  1. 获取窗口句柄
    在页面中添加获取当前窗口句柄的方法:
int getWindowHandle() {
  if (kIsWeb) return 0;
  // Flutter 3.0+ 支持的API,获取当前窗口句柄
  return PlatformDispatcher.instance.views.first.windowHandle;
}
  1. 实现切换逻辑
    在页面State类中添加状态变量和切换方法:
bool _isFullScreen = false;
int _originalWindowStyle = 0;
Rect? _originalWindowBounds;

Future<void> _toggleFullScreen() async {
  final hwnd = getWindowHandle();
  if (hwnd == 0) return;

  _isFullScreen = !_isFullScreen;
  final windowManager = WidgetsBinding.instance.windowManager;

  if (_isFullScreen) {
    // 保存原窗口状态
    _originalWindowStyle = Win32.getWindowLongPtr(hwnd, Win32.GWL_STYLE);
    _originalWindowBounds = await windowManager.getBounds();

    // 移除标题栏、边框和最大化/最小化按钮
    final newStyle = _originalWindowStyle & ~(
      Win32.WS_CAPTION | 
      Win32.WS_THICKFRAME | 
      Win32.WS_MAXIMIZEBOX | 
      Win32.WS_MINIMIZEBOX
    );
    Win32.setWindowLongPtr(hwnd, Win32.GWL_STYLE, newStyle);

    // 设置全屏尺寸(覆盖整个屏幕)
    final screenSize = WidgetsBinding.instance.window.physicalSize / 
                       WidgetsBinding.instance.window.devicePixelRatio;
    await windowManager.setBounds(Rect.fromLTWH(0, 0, screenSize.width, screenSize.height));
  } else {
    // 恢复原窗口样式和位置大小
    Win32.setWindowLongPtr(hwnd, Win32.GWL_STYLE, _originalWindowStyle);
    if (_originalWindowBounds != null) {
      await windowManager.setBounds(_originalWindowBounds!);
    }
  }
  setState(() {});
}
  1. 触发入口
    和方案一完全一致,使用IconButton或AlertDialog调用_toggleFullScreen即可。

注意事项

  • 方案一的window_manager包还支持更多窗口操作(如隐藏任务栏、置顶等),可按需扩展。
  • 方案二的原生API方式需要注意Flutter版本,PlatformDispatcher.instance.views.first.windowHandle仅在Flutter 3.0及以上可用。
  • 测试时需编译Windows桌面应用(flutter run -d windows),模拟器无法完全模拟全屏效果。

内容的提问来源于stack exchange,提问作者YUNN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 10:44:52