一个简单易用的markdown渲染组件
- 支持TOC功能,可以通过Heading快速定位
- 支持代码高亮
- 支持全平台
在开始之前,你可以先体验一下在线 demo 点击体验
import 'package:flutter/material.dart';
import 'package:markdown_widget/markdown_widget.dart';
class MarkdownPage extends StatelessWidget {
final String data;
MarkdownPage(this.data);
@override
Widget build(BuildContext context) => Scaffold(body: buildMarkdown());
Widget buildMarkdown() => MarkdownWidget(data: data);
}
如果你想使用自己的 Column 或者其他列表 Widget, 你可以使用 MarkdownGenerator
Widget buildMarkdown() =>
Column(children: MarkdownGenerator().buildWidgets(data));
或者直接使用 MarkdownBlock
Widget buildMarkdown() =>
SingleChildScrollView(child: MarkdownBlock(data: data));
更多高级用法示例,请参考仓库中的 example/lib/markdown_custom 文件夹:
- video.dart - 自定义 video 标签支持
- latex.dart - LaTeX 数学公式渲染
- mermaid.dart - Mermaid 图表支持(流程图、时序图等)
- html_support.dart - HTML 标签扩展
- custom_node.dart - 自定义节点实现示例
这些示例展示了如何通过自定义标签和功能来扩展本包。
markdown_widget 默认支持夜间模式,只需要使用不同的 MarkdownConfig 即可
Widget buildMarkdown(BuildContext context) {
final isDark = Theme.of(context).brightness == Brightness.dark;
final config = isDark
? MarkdownConfig.darkConfig
: MarkdownConfig.defaultConfig;
final codeWrapper = (child, text, language) =>
CodeWrapperWidget(child, text, language);
return MarkdownWidget(
data: data,
config: config.copy(configs: [
isDark
? PreConfig.darkConfig.copy(wrapper: codeWrapper)
: PreConfig().copy(wrapper: codeWrapper)
]));
}
| 默认模式 | 夜间模式 |
|---|---|
![]() |
![]() |
你可以自定义链接样式和点击事件,比如下面这样
Widget buildMarkdown() => MarkdownWidget(
data: data,
config: MarkdownConfig(configs: [
LinkConfig(
style: TextStyle(
color: Colors.red,
decoration: TextDecoration.underline,
),
onTap: (url) {
///TODO:on tap
},
)
]));
使用TOC非常的简单
final tocController = TocController();
Widget buildTocWidget() => TocWidget(controller: tocController);
Widget buildMarkdown() => MarkdownWidget(data: data, tocController: tocController);
@override
Widget build(BuildContext context) {
return Scaffold(
body: Row(
children: <Widget>[
Expanded(child: buildTocWidget()),
Expanded(child: buildMarkdown(), flex: 3)
],
));
}
代码高亮支持多种主题
import 'package:flutter_highlight/themes/a11y-light.dart';
Widget buildMarkdown() => MarkdownWidget(
data: data,
config: MarkdownConfig(configs: [
PreConfig(theme: a11yLightTheme),
]));
支持全平台的全选和复制功能
由于当前 package 只实现了对于 Markdown tag 的转换,所以默认不支持转换 html 标签。但可以通过扩展的方式来支持这个功能,具体可以参考这里的使用 html_support.dart
在例子中实现了对于Latex的简单支持,具体可以参考这里的实现 latex.dart
示例中包含了对 Mermaid 图表的支持,可以渲染流程图、时序图、状态图等。具体实现可以参考 mermaid.dart
特性:
- 支持多种图表类型(流程图、时序图、状态图、ER 图等)
- 支持主题切换(自动跟随明暗模式)
- 交互式显示模式(仅代码、仅图表、或两者)
- 全屏查看器,支持平移和缩放
- 宽图表独立水平滚动
- 智能缓存和防抖,优化性能
import 'package:markdown_widget/markdown_widget.dart';
import 'markdown_custom/mermaid.dart';
// 基本用法
final isDark = Theme.of(context).brightness == Brightness.dark;
final preConfig = PreConfig(
wrapper: createMermaidWrapper(
config: const MermaidConfig(),
isDark: isDark,
preConfig: preConfig,
),
);
MarkdownWidget(
data: markdown,
config: config.copy(configs: [preConfig]),
)
// 自定义配置
final preConfig = PreConfig(
wrapper: createMermaidWrapper(
config: MermaidConfig(
displayMode: MermaidDisplayMode.codeAndDiagram,
diagramPadding: EdgeInsets.all(16.0),
showLoadingIndicator: true,
),
isDark: isDark,
preConfig: preConfig,
),
);通过向 MarkdownGeneratorConfig 传递 SpanNodeGeneratorWithTag ,可以增加新的 tag,以及这个 tag 所对应的 SpanNode;也可以使用已有的 tag 来对它所对应的 SpanNode 进行覆盖
同时也可以通过 InlineSyntax 与 BlockSyntax 自定义 markdown 字符串的解析规则,并生成新的 tag
可以参考 这个issue 是如何去实现一个自定义tag的
如果你由什么好的想法或者建议,以及使用上的问题, 欢迎来提pr或issue
这里是 markdown_widget 中使用到的其他库
| 库 | 描述 |
|---|---|
| markdown | 解析markdown数据 |
| flutter_highlight | 代码高亮 |
| highlight | 代码高亮 |
| url_launcher | 用于打开链接 |
| visibility_detector | 监听Widget是否可见 |
| scroll_to_index | 让Listview可以根据index来跳转 |



