Flutter中如何格式化从服务器获取的HTML代码片段并展示?
解决Flutter中HTML代码片段格式化后高亮展示的问题
你可以通过先解析并格式化HTML字符串,再传入flutter_highlight组件来实现需求,核心是用dart的html包解析原始HTML,生成带缩进和换行的结构化代码。以下是具体实现步骤:
1. 添加依赖
在pubspec.yaml中引入所需包:
dependencies: flutter: sdk: flutter flutter_highlight: ^0.7.0 # 负责语法高亮 html: ^0.15.4 # 负责HTML解析与格式化
2. 编写HTML格式化函数
这个函数会把原始的单行HTML字符串,转换成带缩进、换行的结构化代码:
import 'package:html/parser.dart' show parse; import 'package:html/dom.dart' as dom; // 自闭合标签列表,避免生成多余的结束标签 const _selfClosingTags = {'img', 'br', 'input', 'meta', 'link', 'hr'}; String formatRawHtml(String rawHtml) { // 解析原始HTML字符串为DOM节点 final document = parse(rawHtml); return _formatDomNode(document.documentElement!, indent: 0); } String _formatDomNode(dom.Node node, {required int indent}) { final indentStr = ' ' * indent; final buffer = StringBuffer(); if (node is dom.Element) { // 拼接开始标签 buffer.write('$indentStr<${node.localName}'); // 拼接标签属性 for (final attr in node.attributes.entries) { buffer.write(' ${attr.key}="${attr.value}"'); } // 处理自闭合标签 if (_selfClosingTags.contains(node.localName)) { buffer.write('/>\n'); return buffer.toString(); } buffer.write('>'); final children = node.children; // 处理子节点 if (children.isNotEmpty) { buffer.write('\n'); for (final child in children) { buffer.write(_formatDomNode(child, indent: indent + 1)); } buffer.write(indentStr); } else if (node.text.trim().isNotEmpty) { // 标签内有文本内容的情况 buffer.write(node.text.trim()); } // 拼接结束标签 buffer.write('</${node.localName}>\n'); } else if (node is dom.Text) { final text = node.text.trim(); if (text.isNotEmpty) { buffer.write('$indentStr$text\n'); } } return buffer.toString(); }
3. 结合flutter_highlight使用
将格式化后的HTML字符串传入HighlightView即可实现带格式的语法高亮:
// 从服务器获取的原始单行HTML final rawHtml = '<div class="container"><h1>HTML教程</h1><p>这是一段示例文本</p><img src="example.jpg" alt="示例图片"></div>'; // 格式化HTML final formattedHtml = formatRawHtml(rawHtml); // 渲染高亮代码 HighlightView( formattedHtml, language: 'html', theme: monokaiTheme, // 可替换为你喜欢的高亮主题 padding: const EdgeInsets.all(12), textStyle: const TextStyle(fontSize: 14), )
额外优化说明
- 可以根据需求调整缩进字符(比如把
' '改成'\t'使用制表符缩进) - 如果需要处理更复杂的HTML场景(比如注释、CDATA等),可以在
_formatDomNode中添加对应节点的处理逻辑
内容的提问来源于stack exchange,提问作者shaik shaheera
相关产品推荐
相关产品推荐

