type
status
date
slug
summary
tags
category
icon
password
 
最近在开发 moli AI,需要支持 markdown 渲染,并且支持跨行的复制。本文主要介绍以下内容:
  1. 如何在 flutter 中使用 markdown
  1. 如何自定义 markdown 样式
  1. 如何让 markdown 支持跨行复制
 
notion image
 

## Flutter Markdown

Flutter Markdown 是 flutter 官方社区提供的一个 markdown 渲染器。支持从简单的 Markdown 标签格式化的纯文本数据中创建富文本输出,包括文本样式、表格、链接等。
 
概述:
  • flutter_markdown 包可以将 Markdown 文本渲染成 Flutter 富文本。
  • 它基于 Dart 的 markdown 包构建,并将 Markdown 解析为抽象语法树(AST)。
  • Markdown 允许在源文本中注入 HTML,但 flutter_markdown 包不支持内联 HTML。
  • 默认情况下,flutter_markdown 包使用 GitHub Flavored Markdown 规范。
 

如何使用

1. 在 pubspec.yaml 中加入 flutter_markdown: ^0.6.18+3 依赖
 
 
然后添加如下代码:
 
 
下图是运行后的结果,可以看到 markdown 正常渲染了,但是代码没有特殊样式,也不支持跨行选中。
notion image
 
接下来,看一下如何自定义代码样式。

如何自定义样式

使用 styleSheet 属性

styleSheet 属性允许您自定义 Markdown 的默认样式。您可以使用 TextStyle 对象来指定字体、颜色、大小等属性。
以下是修改后的代码,可以看到,代码块的颜色已经发生了变化。这将将 h1 标题的字体大小设置为 24 像素,将 code 的字体大小设置为 14 像素,颜色设置为绿色。
 
 
notion image
 
 
继续优化一下样式:
 
这里我使用了 codeblockPaddingcodeblockDecoration
codeblockPaddingcodeblockDecoration 分别用于控制代码块的填充和装饰。
codeblockPadding 属性用于控制代码块的填充。您可以使用 EdgeInsets 对象来指定填充的水平、垂直、左、右、上、下等属性。
这将将代码块的填充设置为 8 像素。
codeblockDecoration 属性用于控制代码块的装饰。您可以使用 BoxDecoration 对象来指定装饰的背景色、边框、圆角等属性。
这将将代码块的背景色设置为灰色,并将边框设置为圆角。
 
notion image
 
不过现在还是不能跨行复制。这里可能的原因是 flutter_markdown 使用许多单独的 widget 来绘制 Markdown,不同的 widget 间不能很好的兼容。

如何支持跨行选择

为了解决跨行选择的问题,这里我们可以使用 flutter_markdown_selectionarea 包来解决。
To use it just replace flutter_markdown dependency in your pubspec.yaml with
and then change all imports from
to
and then you will be able to make multiple paragraphs selectable by using SelectionArea widget:
以下是修改后的代码:
可以看到,现在已经支持跨行选择了。
 
notion image
 

one more thing

虽然已经支持跨行选择,但是你会发现代码块被选中后的颜色并没有变化,这样会让我们很困惑,不确定是否真的被选中。
这里我使用 Flutter Markdown 的 MarkdownElementBuilder 来自定义 Markdown 的渲染方式。
要使用 MarkdownElementBuilder,您需要创建一个 MarkdownElementBuilder 子类,并实现 visitElementAfter() 方法。在 visitElementAfter() 方法中,您可以根据 Markdown 元素的类型来生成自定义的 Flutter 组件。
以下是一个简单的示例:
从下图中已经可以清晰的看到哪些内容被选中了。
 
notion image
 
🎉🎉🎉

遗留问题

  1. 如何让代码块高亮
  1. 代码块高亮后如何选中。

📎 参考文章

  1. flutter_markdown
  1. https://pub.dev/packages/flutter_markdown_selectionarea
  1. [flutter_markdown] Selecting text works only paragraph by paragraph in markdown widget when text is not indented
 
Bilibili gengine 简易使用指南Flutter完全指南:如何实现夜间模式、动态主题和主题切换
Gusibi
Gusibi
后端开发,擅长使用 Python 和 Golang,现在面向AI编程。热爱探索新互联网产品,曾写过小程序。正在学习 Flutter,热衷于技术的探索与进步。
公告
type
status
date
slug
summary
tags
category
icon
password
🎉欢迎访问🎉
-- 感谢您的支持 ---
👏欢迎更新体验👏
 
🤺
关于我