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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 17:25:23