HTML转JSON字符串时特殊上标字符显示异常问题求解
你的问题来自两个核心原因:
- 你当前的解析逻辑只提取HTML片段的纯文本,丢失了
<sup>标签的格式语义,同时原始内容里的Unicode上标字符ˢᵗ没有被兼容处理 - 你项目使用的默认字体不支持
ˢᵗ这类特殊Unicode字符,导致显示为方块乱码
解决思路
- 先完成HTML实体解码
使用Dart官方html包的HtmlUnescape工具类,先把JSON中拿到的转义后的HTML字符(比如<、")转回原始字符,不要直接用parseFragment的text属性丢弃格式:
import 'package:html/parser.dart'; import 'package:html/dom.dart'; import 'package:html_unescape/html_unescape.dart'; Achievement.fromJson(Map<String, dynamic> json) { final unescape = HtmlUnescape(); // 先解码所有HTML实体 String rawTitle = json['titel'] != null ? unescape.convert(json['titel']) : ''; // 后续再处理上标内容 titel = rawTitle; }
- 处理上标显示,两种可选方案:
- 方案1(推荐,保留上标样式):不要用原生Text组件,改用pub.dev上的flutter_html组件,直接渲染处理后的HTML内容,组件会自动识别
<sup>标签渲染为上标,也会自动兼容特殊字符的显示,无需手动解析文本。 - 方案2(使用原生Text组件):把所有特殊上标字符和HTML上标标签统一替换为普通文本,或者用
Text.rich手动实现上标样式,规避特殊字符的字体兼容问题:
// 替换特殊字符示例 rawTitle = rawTitle.replaceAll('ˢᵗ', 'st').replaceAllMapped(RegExp(r'<sup>(.*?)<\/sup>'), (match) => match.group(1)!); // 手动实现上标的Text.rich示例 Text.rich( TextSpan( children: [ const TextSpan(text: 'Herosim in 21'), WidgetSpan( child: Transform.translate( offset: const Offset(0, -4), child: const Text('st', style: TextStyle(fontSize: 10)), ), ), const TextSpan(text: ' Century: The Example of "Dexter"'), ], ), )
- 字体兜底兼容
如果必须保留ˢᵗ这类特殊Unicode字符,给Text组件的style添加fontFamilyFallback属性,配置支持特殊字符的兜底字体,例如:
Text( titel, style: const TextStyle( fontSize: 14, fontWeight: FontWeight.w600, fontFamilyFallback: ['Noto Sans SC', 'Roboto'], ), )
内容的提问来源于stack exchange,提问作者Jiho
相关产品推荐
相关产品推荐

