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

Dart JsonSerializable:如何返回const IconData解决构建报错

解决方法

核心问题在于:从服务器获取的动态数据是运行时确定的,而const修饰的对象必须是编译时常量,所以直接通过Json反序列化得到const IconData是不可能的。报错的根源是你让Dto继承了IconData,导致反序列化出来的非const实例被Flutter的摇树优化机制检测到。

下面提供两种可行的解决方案:

方案一:使用纯数据Dto + 动态创建IconData

放弃让Dto继承IconData,定义一个只承载图标参数的普通可序列化类,在需要使用图标的地方再创建IconData实例:

1. 定义图标配置Dto

@JsonSerializable()
class DrawerIconConfigDto {
  final int codePoint;
  final String? fontFamily;
  final String? fontPackage;
  final bool? matchTextDirection;

  const DrawerIconConfigDto({
    required this.codePoint,
    this.fontFamily,
    this.fontPackage,
    this.matchTextDirection,
  });

  factory DrawerIconConfigDto.fromJson(Map<String, dynamic> json) =>
      _$DrawerIconConfigDtoFromJson(json);

  Map<String, dynamic> toJson() => _$DrawerIconConfigDtoToJson(this);
}

2. 反序列化并创建IconData

// 从服务器获取JSON并反序列化为Dto
final iconConfig = DrawerIconConfigDto.fromJson(serverResponseJson);

// 在需要使用图标的地方创建IconData
final iconData = IconData(
  iconConfig.codePoint,
  fontFamily: iconConfig.fontFamily,
  fontPackage: iconConfig.fontPackage,
  matchTextDirection: iconConfig.matchTextDirection ?? false,
);

这种方式避免了Dto继承IconData带来的非const实例检测问题,同时符合动态获取图标的需求。

方案二:枚举映射预定义const IconData(适用于图标固定的场景)

如果服务器返回的图标是预先确定的有限个,可以先在客户端定义对应的const IconData和枚举,服务器返回枚举值,客户端通过映射获取const实例:

1. 定义图标枚举和映射

enum DrawerIconType {
  home,
  settings,
  profile,
}

// 预定义所有const IconData
const drawerIconMap = {
  DrawerIconType.home: IconData(0xe800, fontFamily: 'CustomIcons'),
  DrawerIconType.settings: IconData(0xe801, fontFamily: 'CustomIcons'),
  DrawerIconType.profile: IconData(0xe802, fontFamily: 'CustomIcons'),
};

2. 定义枚举Dto

@JsonSerializable()
class DrawerIconDto {
  final DrawerIconType iconType;

  const DrawerIconDto({required this.iconType});

  factory DrawerIconDto.fromJson(Map<String, dynamic> json) =>
      _$DrawerIconDtoFromJson(json);

  Map<String, dynamic> toJson() => _$DrawerIconDtoToJson(this);
}

3. 反序列化并获取const IconData

final iconDto = DrawerIconDto.fromJson(serverResponseJson);
// 获取预定义的const IconData
const iconData = drawerIconMap[iconDto.iconType]!;

这种方式完全满足const IconData的要求,也能正常通过摇树优化,适合图标数量固定的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 14:32:21