如何配置ValueChangeObserver使用缓存存储的key实现多主题切换
多值主题切换实现方案
ValueChangeObserver是泛型组件,本身不限制监听值的类型,不需要局限于布尔值场景,直接把泛型替换为下拉菜单返回的int类型,复用你之前写暗黑模式的监听逻辑即可。
- 第一步:先定义下拉选项索引和对应主题的映射关系,避免硬编码散落在各处
// 下拉选项value和主题配置一一对应 final Map<int, ThemeData> appThemeMap = { 1: ThemeData.light().copyWith( primaryColor: Colors.blue, appBarTheme: const AppBarTheme(backgroundColor: Colors.blue), scaffoldBackgroundColor: Colors.white, ), 2: ThemeData.light().copyWith( primaryColor: Colors.white, appBarTheme: const AppBarTheme( backgroundColor: Colors.white, foregroundColor: Colors.black, elevation: 1 ), scaffoldBackgroundColor: Colors.grey.shade50, ), 3: ThemeData.light().copyWith( primaryColor: Colors.brown, appBarTheme: const AppBarTheme(backgroundColor: Colors.brown), scaffoldBackgroundColor: Colors.brown.shade50, ), 4: ThemeData.light().copyWith( primaryColor: Colors.grey, appBarTheme: const AppBarTheme(backgroundColor: Colors.grey), scaffoldBackgroundColor: Colors.grey.shade200, ), };
- 第二步:修改根组件的观察者配置,把泛型从
bool改成int,缓存key和下拉组件的settingKey保持一致
@override Widget build(BuildContext context) { return ValueChangeObserver<int>( cacheKey: keyTheme, // 和下拉组件的key完全一致才能监听到变化 defaultValue: 1, // 和下拉组件默认选中值保持一致 builder: (_, selectedThemeIndex, __) => MaterialApp( title: _title, // 从映射表取对应主题,异常时回退到默认主题避免报错 theme: appThemeMap[selectedThemeIndex] ?? appThemeMap[1]!, home: const PagPrin(), ), ); }
- 第三步:下拉菜单组件不需要额外编写onChange逻辑,同key下的值变化会被观察者自动捕获,触发全局主题重建
Widget buildTheme() => DropDownSettingsTile( settingKey: keyTheme, title: "主题颜色", selected: 1, values: const <int, String>{ 1: '默认蓝', 2: '白色', 3: '棕色', 4: '灰色', }, onChange: (colors) {/* 无需额外处理 */}, );
注意事项:
- 观察者的泛型必须和下拉组件存储的值类型完全匹配,这里下拉存的是int类型的选项键,所以泛型写
int即可- 缓存key必须全局唯一,观察者和设置组件使用的key必须完全相同,否则无法触发监听
- 建议给主题配置加空兜底,避免缓存损坏出现找不到对应主题的报错
内容的提问来源于stack exchange,提问作者user19400370
相关产品推荐
相关产品推荐

