将对象转换为可编码对象失败:“ThemeData”实例
Posted
技术标签:
【中文标题】将对象转换为可编码对象失败:“ThemeData”实例【英文标题】:Converting object to an encodable object failed: Instance of 'ThemeData' 【发布时间】:2021-11-04 04:41:47 【问题描述】:在我的应用程序中,我想保存一个包含ThemeData
、一个布尔值和一个字符串变量的列表。我正在尝试映射该类以将其保存到Shared Preferences
,但在对列表进行编码时出现此错误:
Converting object to an encodable object failed: Instance of 'ThemeData'
这是 CustomThemeModel 类:
class CustomThemeModel
ThemeData myThemeData = new ThemeData();
String themeName;
bool readOnly = false;
CustomThemeModel(
required this.myThemeData,
required this.themeName,
required this.readOnly,
);
CustomThemeModel.fromMap(Map map) :
this.myThemeData = map['myThemeData'],
this.themeName = map['themeName'],
this.readOnly = map['readOnly'];
Map toMap()
return
'myThemeData': this.myThemeData,
'themeName': this.themeName,
'readOnly': this.readOnly,
;
以及将保存列表的 void 方法:
void saveData()
List<String> spList = myThemes.map((e) => json.encode(e.toMap())).toList();
print(spList);
【问题讨论】:
【参考方案1】:您可以尝试像这样强制转换您的 fromMap
构造函数。
CustomThemeModel.fromMap(Map map) :
this.myThemeData = map['myThemeData'] as ThemeData,
this.themeName = map['themeName'] as String,
this.readOnly = map['readOnly'] as bool;
我将在我的主要答案中详细说明。您必须将您拥有的CustomThemeModel
s 转换为地图的用例是什么?为了简单起见并帮助您解决问题,我建议您先以合乎逻辑的方式进行拆分。
我假设您想要一个自定义主题列表,因此请创建一个列表。下面是一个快速模型,可让您以基本方式添加到列表中并构建自定义主题列表。
final List<CustomThemeModel> customThemes = [];
void addToCustomThemes(CustomThemeModel model)
customThemes.add(model);
...
InkWell(
onTap: ()
addToCustomThemes(CustomThemeModel(
myThemeData: ThemeData(),
themeName: 'customThemeName1',
readOnly: false,
),
);
)
你可以很容易地在这个列表中找到一个主题模型。
for (final theme in customThemes)
return theme.where(theme.themeName == 'my theme name');
Edit2:对于您的特定用例,我会做这样的事情。请注意,代码是专门在此处的文本编辑器中键入的,因此如果不进行一些小的调整,它可能无法运行,但想法就在那里。
final List<CustomThemeModel> customThemeModels = [
CustomThemeModel(
myThemeData: ThemeData(),
themeName: 'My name',
readOnly: true,
),
// Add all CustomThemeModels here
];
// Create the list of ThemeData from your custom list
final List<ThemeData> themeData = customThemeModels.map((themeModel)
return themeModel.myThemeData;
).toList();
现在,您的两个列表的顺序是相同的,因此您可以通过提供您提供的名称来找到要使用的主题的索引。
int getIndex(nameToCheck String)
return customThemeModels.indexWhere((theme) => theme.themeName == nameToCheck);
然后您可以使用此索引为您的包提供正确的索引。
【讨论】:
它工作了,但是现在如果我想将保存的数据与 fromMap 一起使用,我会收到如下错误:未处理的异常:类型“字符串”不是类型转换中“主题数据”类型的子类型 您的saveData
方法有些问题。您将主题转换为字符串列表,但您将字符串视为 json 对象。因此,将 String: ThemeData 的键值对转换为原始 String(或 String: String 的键值对)。为什么不将您的自定义主题列表设为一个 List以上是关于将对象转换为可编码对象失败:“ThemeData”实例的主要内容,如果未能解决你的问题,请参考以下文章
Map<int, List<int>> 转换为可编码对象失败
Swift Firebase - 将估计的 ServerTimestamp 与可编码的自定义对象相结合