Flutter应用实现亮色/暗色/系统主题切换及状态保存方案求助
解决方案
要实现无状态管理库的主题切换+持久化,我们可以用StatefulWidget配合shared_preferences插件来完成,具体步骤如下:
1. 添加依赖
在pubspec.yaml中加入shared_preferences:
dependencies: flutter: sdk: flutter shared_preferences: ^2.2.2 # 使用最新版本即可
2. 修改MyApp为StatefulWidget
将原来的StatelessWidget改为StatefulWidget,负责管理主题模式、读取本地存储和更新主题:
import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; class MyApp extends StatefulWidget { const MyApp({super.key}); static void setThemeMode(BuildContext context, ThemeMode mode) { final state = context.findAncestorStateOfType<_MyAppState>()!; state._updateThemeMode(mode); } @override State<MyApp> createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { ThemeMode _themeMode = ThemeMode.system; @override void initState() { super.initState(); _loadSavedTheme(); } // 从本地存储读取保存的主题设置 Future<void> _loadSavedTheme() async { final prefs = await SharedPreferences.getInstance(); final themeIndex = prefs.getInt('theme_mode'); setState(() { _themeMode = ThemeMode.values[themeIndex ?? 2]; // 2对应ThemeMode.system }); } // 更新主题模式并保存到本地 Future<void> _updateThemeMode(ThemeMode mode) async { final prefs = await SharedPreferences.getInstance(); await prefs.setInt('theme_mode', mode.index); setState(() { _themeMode = mode; }); } @override Widget build(BuildContext context) { return MaterialApp( debugShowCheckedModeBanner: false, theme: ThemeData(scaffoldBackgroundColor: Colors.white), darkTheme: ThemeData(scaffoldBackgroundColor: Colors.black), themeMode: _themeMode, home: const HomePage(), ); } }
3. 修改HomePage的按钮逻辑
在HomePage的按钮点击事件中调用MyApp提供的方法来切换主题:
class HomePage extends StatelessWidget { const HomePage({Key? key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( body: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ ElevatedButton( onPressed: () { MyApp.setThemeMode(context, ThemeMode.dark); }, child: const Text('暗色模式'), ), ElevatedButton( onPressed: () { MyApp.setThemeMode(context, ThemeMode.light); }, child: const Text('亮色模式'), ), ElevatedButton( onPressed: () { MyApp.setThemeMode(context, ThemeMode.system); }, child: const Text('跟随系统'), ), ], ), ); } }
关键说明
- 给
MyApp添加静态方法setThemeMode,让子页面可以直接触发主题更新 _loadSavedTheme会在App启动时读取本地存储的主题设置,保证重启后保留用户选择- 使用
ThemeMode.values[index]将存储的整数转换为枚举值,ThemeMode.system的索引为2,作为默认 fallback
内容的提问来源于stack exchange,提问作者Mohammed
相关产品推荐
相关产品推荐

