Flutter主题适配需求:默认跟随系统明暗模式,支持手动切换
解决方案:让Flutter应用启动时优先遵循系统主题,同时保留手动切换功能
下面分步骤修改你已有的代码:
1. 添加持久化依赖(若未添加)
要记住用户的手动切换设置,需用shared_preferences做本地存储,在pubspec.yaml的dependencies中添加:
shared_preferences: ^2.2.2
执行flutter pub get完成依赖安装。
2. 更新ThemeProvider逻辑
修改theme_provider.dart,让它初始化时优先读取用户保存的主题,无保存记录则跟随系统当前明暗模式,同时持久化用户的切换操作:
import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'theme.dart'; class ThemeProvider extends ChangeNotifier { ThemeMode _themeMode; ThemeProvider() { _initTheme(); } // 初始化主题:优先读本地保存设置,无则用系统主题 Future<void> _initTheme() async { final prefs = await SharedPreferences.getInstance(); final savedTheme = prefs.getString('theme_mode'); if (savedTheme != null) { _themeMode = savedTheme == 'light' ? ThemeMode.light : ThemeMode.dark; } else { // 获取系统当前明暗模式 final systemBrightness = WidgetsBinding.instance.window.platformBrightness; _themeMode = systemBrightness == Brightness.light ? ThemeMode.light : ThemeMode.dark; } notifyListeners(); } ThemeMode get themeMode => _themeMode; // 切换主题并保存到本地 Future<void> toggleTheme() async { _themeMode = _themeMode == ThemeMode.light ? ThemeMode.dark : ThemeMode.light; final prefs = await SharedPreferences.getInstance(); await prefs.setString('theme_mode', _themeMode == ThemeMode.light ? 'light' : 'dark'); notifyListeners(); } // 可选:添加重置为系统主题的方法 Future<void> resetToSystem() async { final systemBrightness = WidgetsBinding.instance.window.platformBrightness; _themeMode = systemBrightness == Brightness.light ? ThemeMode.light : ThemeMode.dark; final prefs = await SharedPreferences.getInstance(); await prefs.remove('theme_mode'); notifyListeners(); } }
3. 调整main.dart集成
确保MaterialApp正确使用Provider提供的主题模式:
import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'theme.dart'; import 'theme_provider.dart'; void main() { runApp( ChangeNotifierProvider( create: (_) => ThemeProvider(), child: const MyApp(), ), ); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { final themeProvider = Provider.of<ThemeProvider>(context); return MaterialApp( title: 'Your App', theme: LightMode, // 你的亮主题配置 darkTheme: DarkMode, // 你的暗主题配置 themeMode: themeProvider.themeMode, // 关键:绑定Provider中的主题模式 home: const YourHomePage(), ); } }
核心逻辑说明
- 首次启动:应用自动检测系统明暗模式,匹配对应的主题。
- 用户手动切换后:新主题会被保存到本地,下次启动直接使用用户选择的主题,不再跟随系统(除非调用
resetToSystem重置)。 - 若你使用的是Flutter 3.0+版本,在Widget树内获取系统亮度也可以用
View.of(context).platformDispatcher.platformBrightness,但初始化阶段(Widget树之外)用WidgetsBinding.instance.window.platformBrightness更稳妥。
内容的提问来源于stack exchange,提问作者Cedric Valentin Piehl
相关产品推荐
相关产品推荐

