如何在Flutter中持久化DayNightSwitcher的isDarkModeEnabled状态?
解决主题开关状态同步问题
核心问题分析
当前代码里isDarkModeEnabled硬编码初始值为true,重新进入页面时不会同步全局主题的实际状态;直接在initState中设置状态会因主题变化触发组件重建,导致循环更新。
修复方案
- 从全局主题初始化状态:组件构建时,根据
MyApp的当前主题模式设置开关状态,避免硬编码初始值。 - 监听主题变化更新状态:通过
didChangeDependencies监听全局主题变化,实时同步开关状态。 - 同步本地状态与全局主题:开关回调中同时更新本地状态和全局主题,确保状态一致。
修改后的完整代码
import 'package:day_night_switcher/day_night_switcher.dart'; import 'package:flutter/material.dart'; import 'package:velneoapp/main.dart'; class DayNight extends StatefulWidget { const DayNight({super.key}); @override State<DayNight> createState() => _DayNightState(); } class _DayNightState extends State<DayNight> { late bool _isDarkModeEnabled; @override void didChangeDependencies() { super.didChangeDependencies(); // 从全局主题获取当前状态,同步到本地 final currentThemeMode = MyApp.of(context).currentThemeMode; setState(() { _isDarkModeEnabled = currentThemeMode == ThemeMode.dark; }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text("Dark mode")), body: SizedBox.expand( child: Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.center, children: [ const Text( 'Changes from dark mode to light mode, and vice-versa', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold), ), DayNightSwitcher( isDarkModeEnabled: _isDarkModeEnabled, onStateChanged: (isDarkModeEnabledVar) { setState(() { _isDarkModeEnabled = isDarkModeEnabledVar; }); // 更新全局主题 MyApp.of(context).changeTheme( isDarkModeEnabledVar ? ThemeMode.dark : ThemeMode.light, ); }, ), ], ), ), ); } }
关键说明
didChangeDependencies:每次依赖(比如全局主题)变化时自动调用,用来同步全局主题到本地状态,避免页面重建后状态错位。- 同步本地状态:开关回调中先更新本地
_isDarkModeEnabled,再修改全局主题,确保UI显示和状态实时匹配。 - 避免循环触发:不再在
initState中直接触发状态更新,通过依赖变化的回调同步,不会导致无限重建循环。
内容的提问来源于stack exchange,提问作者Quelox
相关产品推荐
相关产品推荐

