You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter存储含ThemeData对象到SharedPreferences报编码错误如何解决?

问题原因

json.encode仅支持序列化Dart内置基础类型(数字、字符串、布尔、列表、键为字符串且值为可序列化类型的Map),你直接把ThemeData实例放入Map中序列化时,Json序列化器无法识别自定义的ThemeData类,就会抛出转换失败的错误。

解决方案

不要直接存储ThemeData实例,仅存储你自定义修改过的ThemeData的属性值,反序列化时再用这些属性重新构造ThemeData实例即可。

修改后的CustomThemeModel参考代码如下:

class CustomThemeModel {
  ThemeData myThemeData;
  String themeName;
  bool readOnly = false;

  CustomThemeModel({
    required this.myThemeData,
    required this.themeName,
    required this.readOnly,
  });

  // 反序列化:从存储的Map还原实例
  CustomThemeModel.fromMap(Map map) :
        themeName = map['themeName'],
        readOnly = map['readOnly'],
        // 用存储的属性重新构造ThemeData,可根据你的实际自定义属性增删字段
        myThemeData = ThemeData(
          brightness: Brightness.values[map['themeBrightnessIndex']],
          primaryColor: Color(map['primaryColorValue']),
          // 你自定义修改过的其他ThemeData属性都可以在此处补充还原
        );

  // 序列化:仅把需要的ThemeData属性转成基础类型存入Map
  Map<String, dynamic> toMap(){
    return{
      // 只存你修改过的ThemeData属性,转成可序列化的基础类型
      'themeBrightnessIndex': myThemeData.brightness.index,
      'primaryColorValue': myThemeData.primaryColor.value,
      // 你自定义的其他ThemeData属性在此处补充存储
      'themeName': themeName,
      'readOnly': readOnly,
    };  
  }
}

修改完成后原有的saveData方法就可以正常执行,序列化后的字符串列表可以直接存入SharedPreferences。

注意事项

  • 不需要存储ThemeData的所有属性,仅需要存储你主动修改过的配置,未修改的属性使用ThemeData默认值即可,可以大幅减少存储的冗余数据
  • 所有Color类型都可以通过.value属性转为int类型存储,读取时传入Color(存储的int值)即可还原颜色
  • 枚举类型可以通过.index存储为int,读取时用枚举类.values[存储的int值]还原枚举

内容的提问来源于stack exchange,提问作者KrekZsole

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 19:24:02