主题系统的目标是统一视觉与可维护性。本文基于 provider + shared_preferences 给出一套可复用的主题实现范式:主题定义、状态管理、持久化与切换。
0. 依赖
dependencies:
provider: ^6.0.5
shared_preferences: ^2.1.2
1. 定义主题模型
enum AppThemeType { light, dark }
class AppTheme {
static ThemeData light = ThemeData(
brightness: Brightness.light,
colorScheme: ColorScheme.fromSeed(seedColor: Colors.teal),
);
static ThemeData dark = ThemeData(
brightness: Brightness.dark,
colorScheme: ColorScheme.fromSeed(seedColor: Colors.teal, brightness: Brightness.dark),
);
}
2. 主题状态管理
class ThemeStore extends ChangeNotifier {
AppThemeType _type = AppThemeType.light;
AppThemeType get type => _type;
ThemeData get theme => _type == AppThemeType.light ? AppTheme.light : AppTheme.dark;
void setTheme(AppThemeType type) {
_type = type;
notifyListeners();
}
}
3. 注入与应用
ChangeNotifierProvider(
create: (_) => ThemeStore(),
child: Consumer<ThemeStore>(
builder: (_, store, __) => MaterialApp(
theme: store.theme,
),
),
)
4. 持久化主题
class ThemeStore extends ChangeNotifier {
AppThemeType _type = AppThemeType.light;
Future<void> load() async {
final prefs = await SharedPreferences.getInstance();
final saved = prefs.getString('theme');
_type = saved == 'dark' ? AppThemeType.dark : AppThemeType.light;
notifyListeners();
}
Future<void> setTheme(AppThemeType type) async {
_type = type;
final prefs = await SharedPreferences.getInstance();
await prefs.setString('theme', type == AppThemeType.dark ? 'dark' : 'light');
notifyListeners();
}
}
5. UI 切换按钮
IconButton(
icon: const Icon(Icons.brightness_6),
onPressed: () {
final store = context.read<ThemeStore>();
store.setTheme(store.type == AppThemeType.dark ? AppThemeType.light : AppThemeType.dark);
},
)
6. 实践清单
- 主题模型统一定义
- Provider 管理主题状态
- 持久化用户偏好
- 全局入口切换
总结
主题系统是设计系统的技术承载。统一入口、状态管理与持久化,才能让主题可维护。