Flutter文本高亮插件marked_text的使用

Flutter文本高亮插件marked_text的使用

特性

marked_text 允许标记文本的某些部分,以便以不同的方式渲染它们,并附加行为(如手势识别)。

构建

由于该插件允许根据其ID动态获取图标,因此在构建Flutter应用时,必须提供标志 --no-tree-shake-icons

开始使用

设置默认选项
MarkedText.setDefaults({
  // 默认将所有图标设置为橙色
  "icon": MarkOptions(
    styleBuilder: (context, text, payload, defaultStyle) => defaultStyle?.copyWith(color: Colors.orange),
  ),
  // 将斜体文本设为半透明,记得将其设为斜体
  "i": MarkOptions(
    styleBuilder: (context, text, payload, defaultStyle) => defaultStyle?.copyWith(color: Colors.black54, fontStyle: FontStyle.italic),
  ),
  // 将粗体文本设为更大,记得将其设为粗体
  "b": MarkOptions(
    styleBuilder: (context, text, payload, defaultStyle) => defaultStyle?.copyWith(fontSize: 20, fontWeight: FontWeight.bold),
  )
});
渲染文本

定义自定义标记或使用已实现的标记。

MarkedText(
  source: rawStringSource,
  textAlign: TextAlign.start,
  marks: [
    Mark.bold(), // 粗体标记
    Mark.italic(), // 斜体标记
    Mark.link(), // 链接标记
    Mark.icon(), // 图标标记
    Mark(
      id: "custom",
      options: MarkOptions(
        onTap: (text, payload) => debugPrint("tapped text $text with payload $payload"), // 点击事件
        styleBuilder: (context, text, payload, defaultStyle) =>
            defaultStyle?.copyWith(decoration: TextDecoration.underline, color: Colors.amberAccent), // 自定义样式
      ),
    ),
    Mark(
      id: "longpress",
      options: MarkOptions(
        recognizerFactory: (text, payload) =>
            LongPressGestureRecognizer(duration: const Duration(milliseconds: 200))..onLongPress = () => debugPrint("long pressed text $text with payload $payload"), // 长按事件
        styleBuilder: (context, text, payload, defaultStyle) =>
            defaultStyle?.copyWith(decoration: TextDecoration.underline, color: Colors.red), // 自定义样式
      ),
    )
  ],
)
文本源

以下文本展示了如何在文本中定义标记。

Lorem ${[ipsum]longpress()}, lorem ${[ipsum]i()}, lorem ${[ipsum]b()}

使用方法

标记的 id 定义了如何在源字符串中识别标记。正则表达式 必须 包含三个命名组,并且必须是有限的,即它必须包含可以识别相应标记结束的符号。

  • text 通常是要显示的文本
  • id 用于标识应使用哪个标记的类型(ID)
  • payload 是标记的有效载荷

组是命名的,因此它们可以在源字符串中的任何位置放置。

默认的正则表达式匹配这种形式的标记:

${[text]type(payload)}

强烈建议深入测试正则表达式,以确保其正确运行。

算法执行以下操作:

  • 匹配第一个标记并提取其信息
  • 复制匹配后的剩余字符串
  • 重复

因此,请确保正则表达式仅匹配必要的内容,并且能够在正确的点上确定性地停止。

完整示例Demo

import "package:flutter/gestures.dart";
import "package:flutter/material.dart";
import "package:marked_text/marked_text.dart";

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: "Flutter Demo",
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: "Marked text example"),
    );
  }
}

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  [@override](/user/override)
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  // 示例文本源
  String rawStringSource = """
Welcome to the \${[example]i()} of the package \${[mapplet_text]b()}.
To check out more information, be sure to visit the package on \${[pub.dev]lk(https://pub.dev/packages/marked_text)}.
This package allows to mark arbitrary text spans in order to customize the appearance and to include custom callbacks when interacting with the marks.
It is also possible to include custom icons in the text using the int code of the \${[Flutter Material Icons]lk(https://api.flutter.dev/flutter/material/Icons-class.html#constants)}.
\${[Icon with text]icon(0xf53f)}
\${[Another icon]icon(0xe062)}

\${[Custom mark]custom(first payload)}
\${[Custom mark]custom(second payload)}

\${[Long press text]longpress(long press payload)}
""";

  [@override](/user/override)
  void initState() {
    super.initState();
    // 设置一些默认选项
    MarkedText.setDefaults(
      textStyle: const TextStyle(color: Colors.white, fontSize: 20),
      marksOptions: {
        // 默认将所有图标设置为橙色
        "icon": MarkOptions(
          styleBuilder: (context, text, payload, defaultStyle) => defaultStyle?.copyWith(color: Colors.orange),
        ),
        // 将斜体文本设为半透明,记得将其设为斜体
        "i": MarkOptions(
          styleBuilder: (context, text, payload, defaultStyle) => defaultStyle?.copyWith(color: Colors.black54, fontStyle: FontStyle.italic),
        ),
        // 将粗体文本设为更大,记得将其设为粗体
        "b": MarkOptions(
          styleBuilder: (context, text, payload, defaultStyle) => defaultStyle?.copyWith(fontSize: 20, fontWeight: FontWeight.bold),
        ),
      },
    );
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.blueGrey,
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: MarkedText(
          source: rawStringSource,
          textAlign: TextAlign.start,
          marks: [
            Mark.bold(), // 粗体标记
            Mark.italic(), // 斜体标记
            Mark.link(), // 链接标记
            Mark.icon(), // 图标标记
            Mark(
              id: "custom",
              options: MarkOptions(
                onTap: (text, payload) => debugPrint("tapped text $text with payload $payload"), // 点击事件
                styleBuilder: (context, text, payload, defaultStyle) =>
                    defaultStyle?.copyWith(decoration: TextDecoration.underline, color: Colors.amberAccent), // 自定义样式
              ),
            ),
            Mark(
              id: "longpress",
              options: MarkOptions(
                recognizerFactory: (text, payload) =>
                    LongPressGestureRecognizer(duration: const Duration(milliseconds: 200))..onLongPress = () => debugPrint("long pressed text $text with payload $payload"), // 长按事件
                styleBuilder: (context, text, payload, defaultStyle) =>
                    defaultStyle?.copyWith(decoration: TextDecoration.underline, color: Colors.red), // 自定义样式
              ),
            ),
          ],
        ),
      ),
    );
  }
}

更多关于Flutter文本高亮插件marked_text的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter文本高亮插件marked_text的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


marked_text 是一个用于在 Flutter 应用中实现文本高亮的插件。它允许你根据特定的规则或模式,将文本中的某些部分高亮显示。这个插件非常适用于需要在文本中突出显示关键词、链接、代码块等场景。

安装 marked_text

首先,你需要将 marked_text 添加到你的 pubspec.yaml 文件中:

dependencies:
  flutter:
    sdk: flutter
  marked_text: ^1.0.0  # 请根据实际情况使用最新版本

然后,运行 flutter pub get 来安装依赖。

基本用法

以下是一个简单的 marked_text 使用示例:

import 'package:flutter/material.dart';
import 'package:marked_text/marked_text.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Marked Text Example'),
        ),
        body: Center(
          child: MarkedText(
            text: 'Hello *world* and _Flutter_!',
            markers: [
              Marker(
                style: TextStyle(fontWeight: FontWeight.bold),
                pattern: r'\*[^*]+\*', // 匹配 *word*
              ),
              Marker(
                style: TextStyle(fontStyle: FontStyle.italic),
                pattern: r'_[^_]+_', // 匹配 _word_
              ),
            ],
          ),
        ),
      ),
    );
  }
}
回到顶部