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

Flutter Windows如何创建透明窗口实现自定义形状圆角界面

Flutter Windows 透明圆角自定义窗口实现方案

以下方案可直接实现全透明、自定义形状/圆角的无边框窗口,完全满足悬浮式仪表盘类UI的开发需求。


前置依赖准备

使用社区维护最稳定的window_manager插件做窗口控制,避免直接写大量Win32 API兼容代码。
在pubspec.yaml中添加依赖:

dependencies:
  flutter:
    sdk: flutter
  window_manager: ^0.3.9

第一步:原生层配置(解决黑边核心步骤)

Flutter默认的Windows窗口模板带原生边框、不透明背景,必须先修改原生配置,否则会出现启动黑边、透明失效问题。
打开windows/runner/main.cpp文件,做两处修改:

  1. 修改窗口类注册配置,将背景刷设为空
WNDCLASS window_class = {};
// 其他配置保持不变,仅修改hbrBackground字段
window_class.hbrBackground = nullptr;
  1. 修改窗口创建样式,替换原有的带边框窗口样式
HWND window = CreateWindow(
    window_class_name,
    title.c_str(),
    WS_POPUP, // 替换原有的WS_OVERLAPPEDWINDOW等默认样式,移除原生边框/标题栏
    CW_USEDEFAULT, CW_USEDEFAULT, width, height,
    nullptr, nullptr, instance, this);
// 开启分层窗口透明属性
SetLayeredWindowAttributes(window, RGB(0,0,0), 255, LWA_ALPHA);

第二步:Flutter层窗口初始化

在main.dart中初始化窗口配置,开启透明、无边框属性,等首帧渲染完成再显示窗口,避免启动闪烁:

import 'package:flutter/material.dart';
import 'package:window_manager/window_manager.dart';

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

  const WindowOptions windowOptions = WindowOptions(
    size: Size(1280, 820),
    transparent: true,
    frameless: true,
    center: true,
    backgroundColor: Colors.transparent,
    skipTaskbar: false,
    titleBarStyle: TitleBarStyle.hidden,
  );

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

  runApp(const MyApp());
}

第三步:自定义窗口形状与交互

透明窗口开启后,Flutter渲染内容之外的区域会完全透过去,你可以自由绘制任意形状的窗口:

  • 圆角矩形窗口:根容器设置圆角+裁剪,加外阴影模拟悬浮感
  • 异形窗口:用ClipPath包裹根组件,自定义绘制路径即可实现任意非矩形形状
  • 交互补全:替换原生标题栏的拖拽、缩放、窗口操作按钮功能

最小可运行的圆角窗口示例代码:

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        // *注意:从MaterialApp到根容器的所有父级组件,背景必须设为透明*
        backgroundColor: Colors.transparent,
        body: Container(
          decoration: BoxDecoration(
            // 窗口主背景色,可替换为渐变、图片等任意样式
            color: const Color(0xFF1C1C28),
            // 自定义圆角大小
            borderRadius: BorderRadius.circular(24),
            // 外阴影增强悬浮质感,和仪表盘类UI的视觉效果匹配
            boxShadow: [
              BoxShadow(
                color: Colors.black.withOpacity(0.35),
                blurRadius: 50,
                spreadRadius: 6,
              )
            ],
          ),
          // 必须开启抗锯齿裁剪,否则圆角边缘会有硬锯齿
          clipBehavior: Clip.antiAlias,
          child: Stack(
            children: [
              Column(
                children: [
                  // 顶部可拖拽标题栏
                  DragToMoveArea(
                    child: Container(
                      height: 56,
                      padding: const EdgeInsets.symmetric(horizontal: 24),
                      child: Row(
                        mainAxisAlignment: MainAxisAlignment.spaceBetween,
                        children: [
                          const Text(
                            "个人财务仪表盘",
                            style: TextStyle(color: Colors.white, fontSize: 16, fontWeight: FontWeight.w500),
                          ),
                          // 窗口操作按钮
                          Row(
                            children: [
                              IconButton(
                                onPressed: () => windowManager.minimize(),
                                icon: const Icon(Icons.remove, color: Colors.white70, size: 20),
                              ),
                              IconButton(
                                onPressed: () => windowManager.maximize(),
                                icon: const Icon(Icons.crop_din, color: Colors.white70, size: 18),
                              ),
                              IconButton(
                                onPressed: () => windowManager.close(),
                                icon: const Icon(Icons.close, color: Colors.white70, size: 20),
                              ),
                            ],
                          )
                        ],
                      ),
                    ),
                  ),
                  // 下方写你的业务页面内容即可,毛玻璃、渐变等效果都可以正常渲染
                  const Expanded(
                    child: Center(
                      child: Text("页面内容区域", style: TextStyle(color: Colors.white70)),
                    ),
                  )
                ],
              ),
              // 窗口边缘拖拽缩放区域,实现和原生窗口一致的边缘拉伸缩放效果
              const ResizableBorderArea(
                enableResizeEdges: ResizeEdge.all,
                child: SizedBox.expand(),
              )
            ],
          ),
        ),
      ),
    );
  }
}

常见问题排查

  • 窗口出现方形不透明底色:检查从MaterialApp、Scaffold到根容器之间的所有组件,是否设置了不透明的backgroundColor,全部改为透明即可
  • 圆角边缘有白/黑边:确认根容器开启了Clip.antiAlias裁剪,同时不要调用系统Dwm的圆角接口,避免系统绘制的圆角和Flutter绘制的圆角重叠
  • 窗口点击穿透:检查原生窗口样式是否误加了WS_EX_TRANSPARENT属性,或者误调用了windowManager.setIgnoreMouseEvents(true),移除即可
  • 启动闪黑/白屏:必须使用waitUntilReadyToShow方法,等Flutter首帧渲染完成后再显示窗口,不要提前调用show方法

内容的提问来源于stack exchange,提问作者RHS.Dev

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 21:27:22