Flutter如何即时监听设备深色主题切换 无需重启应用即可生效
Flutter应用跟随系统即时切换深色主题解决方案
你当前代码的核心问题是顶层MaterialApp未监听系统亮度变化事件触发重建,虽然已经配置了themeMode: ThemeMode.system,但系统偏好变更时没有触发UI重绘,就需要重启才能生效。
修复步骤
- 将根组件修改为StatefulWidget,混入
WidgetsBindingObserver监听系统事件 - 注册/移除系统事件监听器
- 重写亮度变化回调方法,触发根组件重建
完整实现代码
import 'package:flutter/material.dart'; void main() { runApp(const MyApp()); } class MyApp extends StatefulWidget { const MyApp({super.key}); @override State<MyApp> createState() => _MyAppState(); } class _MyAppState extends State<MyApp> with WidgetsBindingObserver { @override void initState() { super.initState(); // 注册系统变化监听器 WidgetsBinding.instance.addObserver(this); } @override void dispose() { // 销毁前移除监听器,避免内存泄漏 WidgetsBinding.instance.removeObserver(this); super.dispose(); } // 系统亮度变更时自动触发该回调 @override void didChangePlatformBrightness() { super.didChangePlatformBrightness(); // 触发根组件重建,MaterialApp会自动读取最新的系统亮度应用对应主题 setState(() {}); } @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( brightness: Brightness.light ), darkTheme: ThemeData( brightness: Brightness.dark ), themeMode: ThemeMode.system, home: const MyHomePage(title: 'Flutter Demo Home Page'), ); } } // 你的原有MyHomePage代码无需修改 class MyHomePage extends StatelessWidget { const MyHomePage({super.key, required this.title}); final String title; @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text(title)), body: const Center(child: Text("主题跟随系统自动切换测试")), ); } }
额外注意事项
- Flutter 3.16及以上版本部分场景默认支持自动监听,但如果你的根组件有缓存逻辑,仍需添加上述监听逻辑
- 如果你的应用支持手动切换主题模式,可以把
themeMode的值存入状态变量,在setState时同步更新即可同时支持手动+自动切换 - 若安卓端修改后仍不生效,检查
android/app/src/main/AndroidManifest.xml中Activity配置,不要手动拦截uiMode配置变更
内容的提问来源于stack exchange,提问作者Wannabe
相关产品推荐
相关产品推荐

