如何在Flutter应用中监听Windows系统主题(明暗模式)变化?
监听Windows系统主题变化以动态切换Flutter应用主题
Windows平台下,Flutter原生的didChangePlatformBrightness方法不会响应系统主题切换事件,需要通过Flutter平台通道(MethodChannel)结合Windows原生API来实现监听。以下是具体实现方案:
一、Windows原生端实现(监听系统主题变化)
打开Flutter项目的windows目录,修改win32_window.cpp文件:
- 在文件顶部添加必要的头文件:
#include <wchar.h>
- 在窗口过程函数
WndProc的switch语句中,添加WM_SETTINGCHANGE消息处理逻辑:
LRESULT CALLBACK WndProc(HWND window, UINT message, WPARAM w_param, LPARAM l_param) { // 保留原有代码... switch (message) { // 其他case保留... case WM_SETTINGCHANGE: // 当系统沉浸式颜色集(对应深色/浅色模式)变化时触发 if (l_param && wcscmp(reinterpret_cast<LPCWSTR>(l_param), L"ImmersiveColorSet") == 0) { // 通过MethodChannel向Dart端发送主题变化事件 if (flutter_controller_) { flutter_controller_->engine()->InvokeMethod("systemBrightnessChanged", nullptr); } } break; // 其他case保留... } // 保留原有代码... }
二、Dart端实现(接收事件并更新主题)
在Flutter Dart代码中,通过MethodChannel接收Windows端发送的事件,然后动态切换应用主题:
import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatefulWidget { const MyApp({super.key}); @override State<MyApp> createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { final MethodChannel _themeChannel = const MethodChannel('com.example.theme_listener'); Brightness _currentSystemBrightness = WidgetsBinding.instance.window.platformBrightness; @override void initState() { super.initState(); // 注册MethodChannel回调 _themeChannel.setMethodCallHandler(_handleMethodCall); } Future<void> _handleMethodCall(MethodCall call) async { if (call.method == 'systemBrightnessChanged') { // 重新获取系统当前亮度模式 final newBrightness = WidgetsBinding.instance.window.platformBrightness; if (newBrightness != _currentSystemBrightness) { setState(() { _currentSystemBrightness = newBrightness; }); } } } @override Widget build(BuildContext context) { return MaterialApp( title: 'Windows Theme Sync', theme: ThemeData.light(), darkTheme: ThemeData.dark(), // 根据系统亮度自动切换主题模式 themeMode: _currentSystemBrightness == Brightness.dark ? ThemeMode.dark : ThemeMode.light, home: const HomePage(), ); } } class HomePage extends StatelessWidget { const HomePage({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text('主题同步测试')), body: Center( child: Text( Theme.of(context).brightness == Brightness.dark ? '当前为深色模式' : '当前为浅色模式', style: const TextStyle(fontSize: 24), ), ), ); } }
关键说明
- Windows系统切换深色/浅色模式时,会发送
WM_SETTINGCHANGE消息,其中lParam为ImmersiveColorSet时对应主题亮暗变化。 - 通过MethodChannel将原生事件传递到Dart端,再通过
setState更新应用主题。 - 无需依赖第三方包,完全基于Flutter原生能力和Windows API实现。
内容的提问来源于stack exchange,提问作者Darya
相关产品推荐
相关产品推荐

