【开源鸿蒙Flutter跨平台开发学习笔记 】DAY12:markdown解析插件详解
override?'info';),// 自定义语法扩展// 渲染器扩展),]);
·
一、flutter_markdown_plus 解析插件详解
当小鱼想去了解 flutter_markdown插件的时候,发现已经有增强版啦:flutter_markdown_plus,就一起学习一下吧。
1、官网
https://pub.dev/packages/flutter_markdown_plus
2、架构
输入Markdown文本
↓
语法解析(markdown → AST)
↓
AST转换(自定义节点处理)
↓
Widget树构建
↓
Flutter渲染
3、核心流程解析
1)Markdown → AST 解析
// 使用扩展的解析器
final markdown = Markdown(
extensionSet: ExtensionSet.gitHubFlavoredWithPlus,
inlineSyntaxes: [...customSyntaxes],
blockSyntaxes: [...customSyntaxes],
);
// 解析为抽象语法树
final document = markdown.parse(markdownText);
没想到吧,markdow UI是ListView实现的!

2)AST → Widget 转换
// 1、节点映射
class MarkdownBuilderPlus extends MarkdownBuilder {
@override
Widget visitElementAfter(Element element, TextStyle? preferredStyle) {
// 自定义节点处理
switch (element.tag) {
case 'custom-table':
return _buildCustomTable(element);
case 'math':
return _buildMathFormula(element);
case 'alert':
return _buildAlertBox(element);
}
// 默认处理
return super.visitElementAfter(element, preferredStyle);
}
}
// 2、自定义渲染器
class MarkdownPlus extends MarkdownWidget {
const MarkdownPlus({
required String data,
MarkdownStyleSheet? styleSheet,
SyntaxHighlighter? syntaxHighlighter,
}) : super(
data: data,
styleSheet: styleSheet,
syntaxHighlighter: syntaxHighlighter,
builders: {
'table': CustomTableBuilder(),
'math': KatexBuilder(),
'emoji': EmojiBuilder(),
},
extensionSet: _createExtensionSet(),
);
}
3)、表格特性增强
class EnhancedTableBuilder extends MarkdownElementBuilder {
@override
Widget visitElementAfter(Element element, _) {
// 解析表格数据
final tableData = _parseTable(element);
return Table(
border: TableBorder.all(color: Colors.grey[300]!),
children: tableData.rows.map((row) {
return TableRow(
children: row.cells.map((cell) {
return Container(
padding: EdgeInsets.all(8),
child: MarkdownBody(data: cell.content),
);
}).toList(),
);
}).toList(),
);
}
}
4)、数学公式增强
// 集成 KaTeX 或 MathJax
class MathBuilder implements MarkdownElementBuilder {
@override
Widget visitElementAfter(Element element, _) {
final tex = element.textContent;
return FutureBuilder(
future: _renderMath(tex), // 调用JS引擎或原生库
builder: (context, snapshot) {
if (snapshot.hasData) {
return CustomPaint(painter: MathPainter(snapshot.data!));
}
return CircularProgressIndicator();
},
);
}
}
5)、自定义容器
class AlertBoxBuilder extends MarkdownElementBuilder {
final Map<String, Color> alertTypes = {
'info': Colors.blue,
'warning': Colors.orange,
'danger': Colors.red,
};
@override
Widget visitElementAfter(Element element, _) {
final type = element.attributes['type'] ?? 'info';
return Container(
decoration: BoxDecoration(
color: alertTypes[type]!.withOpacity(0.1),
border: BorderLeft: BorderSide(color: alertTypes[type]!, width: 4),
),
padding: EdgeInsets.all(12),
child: MarkdownBody(data: element.textContent),
);
}
}
4、性能优化策略
1)、懒加载与缓存
class CachedMarkdown extends StatefulWidget {
@override
Widget build(BuildContext context) {
return FutureBuilder<Widget>(
future: _cachedMarkdown(), // 缓存解析结果
builder: (context, snapshot) {
return snapshot.data ?? Placeholder();
},
);
}
}
2)增量更新
// 使用 KeyedSubtree 实现局部更新
class IncrementalMarkdown extends StatelessWidget {
final String markdown;
final String previousMarkdown;
@override
Widget build(BuildContext context) {
// 对比差异,只更新变化的部分
final diff = _calculateDiff(previousMarkdown, markdown);
return KeyedSubtree(
key: ValueKey(diff.changedBlocks),
child: MarkdownPlus(data: markdown),
);
}
}
5、扩展机制
1)自定义语法注册
extensionSet = ExtensionSet.gitHubFlavored.addAll([
// 自定义语法扩展
CustomBlockSyntax(),
CustomInlineSyntax(),
// 渲染器扩展
CustomHtmlTagExtension(
tags: ['video', 'audio', 'chart'],
builder: CustomMediaBuilder(),
),
]);
2)插件系统
class MarkdownPlusPlugin {
final List<MarkdownElementBuilder> builders;
final List<BlockSyntax> blockSyntaxes;
final List<InlineSyntax> inlineSyntaxes;
void register(MarkdownPlusController controller) {
controller.registerBuilders(builders);
controller.registerSyntaxes(blockSyntaxes, inlineSyntaxes);
}
}
更多推荐
所有评论(0)