Flutter富文本扩展插件expandable_richtext的使用

发布于 1周前 作者 eggper 来自 Flutter

Flutter富文本扩展插件expandable_richtext的使用

简介

Expandable RichText 是一个用于Flutter的文本组件,它允许你初始只显示一定数量的行数,对于较长的文本可以进行折叠和展开操作。此外,它还支持点击@‌mention、#hashtag和超链接,并且你可以为这些元素定义样式。

主要特性

  • 折叠和展开文本
  • 自定义“展开”和“收起”文本
  • 控制是否在展开/收起文本中显示省略号
  • 展开和收起动画效果
  • 扩展变化事件回调
  • 应用不同的样式到@‌mention、#hashtag、超链接和文本片段
  • 处理@‌mention、#hashtag、超链接和文本片段的点击事件
  • 编程方式控制文本的展开和收起

示例

快速开始

添加依赖

首先,在pubspec.yaml文件中添加依赖:

dependencies:
  expandable_richtext: 1.0.7

然后,在Dart代码中导入包:

import 'package:expandable_rich_text/expandable_richtext.dart';

使用方法

基础用法

如果你的文本超过了两行,可以像下面这样使用:

Widget build(BuildContext context) {
  return ExpandableRichText(
    text: "这里是一段很长的文本...",
    expandText: 'show more',
    collapseText: 'show less',
    maxLines: 2,
    linkColor: Colors.blue,
  );
}

高级用法

当你的文本包含@‌mention、#hashtag、超链接和自定义标签时,你可以更细致地设置样式和交互行为:

Widget build(BuildContext context) {
  return ExpandableRichText(
    "这是一段包含 @用户, #话题, 和 <tag>自定义标签</tag> 的文本。",
    expandText: 'show more',
    collapseText: 'show less',
    maxLines: 1,
    linkColor: Colors.blue,
    mentionStyle: const TextStyle(
      color: Colors.blueAccent, 
      fontSize: 16, 
      fontWeight: FontWeight.bold
    ),
    hashtagStyle: const TextStyle(
      fontSize: 16, 
      color: Colors.white, 
      backgroundColor: Colors.black87
    ),
    urlStyle: const TextStyle(
      color: Colors.lightBlueAccent, 
      decoration: TextDecoration.underline
    ),
    customTagStyle: const TextStyle(
      fontWeight: FontWeight.bold,
      fontStyle: FontStyle.italic,
      fontSize: 16,
      color: Colors.white,
      backgroundColor: Colors.lightBlueAccent,
      decoration: TextDecoration.underline
    )
  );
}

更多配置项

以下是更多可配置选项的例子:

Widget build(BuildContext context) {
  return ExpandableRichText(
    "这是一段包含 @用户, #话题, 和 <tag>自定义标签</tag> 的文本。",
    expandText: 'show more',
    collapseText: 'show less',
    expanded: false,
    onExpandedChanged: (flag) => {},
    toggleTextColor: Colors.black,
    showEllipsis: true,
    toggleTextStyle: const TextStyle(
        fontSize: 12, 
        color: Colors.blue, 
        decoration: TextDecoration.underline),
    urlStyle: const TextStyle(
        color: Colors.lightBlueAccent, 
        decoration: TextDecoration.underline),
    onUrlTap: (url) => {},
    hashtagStyle: const TextStyle(
        fontSize: 16, 
        color: Colors.white, 
        backgroundColor: Colors.black87),
    mentionStyle: const TextStyle(
        color: Colors.blueAccent, 
        fontSize: 16, 
        fontWeight: FontWeight.bold),
    onMentionTap: (mention) => {},
    customTagStyle: const TextStyle(
        fontWeight: FontWeight.bold,
        fontStyle: FontStyle.italic,
        fontSize: 16,
        color: Colors.white,
        backgroundColor: Colors.lightBlueAccent,
        decoration: TextDecoration.underline),
    onCustomTagTap: (tag) => {},
    expandOnTextTap: true,
    collapseOnTextTap: true,
    style: const TextStyle(color: Colors.black, fontSize: 24),
    textDirection: TextDirection.ltr,
    textAlign: TextAlign.start,
    textScaleFactor: 1.0,
    maxLines: 2,
    animation: true,
    animationDuration: const Duration(milliseconds: 200),
    animationCurve: Curves.fastLinearToSlowEaseIn,
  );
}

示例Demo

为了更好地理解如何使用这个插件,以下是一个完整的demo示例:

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

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

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

  @override
  Widget build(BuildContext context) {
    const title = "Expandable Rich Text Example";
    return MaterialApp(
      title: title,
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MyHomePage(title: title),
    );
  }
}

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

  final String title;

  @override
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    // Margin
    const verticalMargin = SizedBox(height: 20);
    const titleMargin = SizedBox(height: 8);

    // Simple text
    final simpleTextTitle = Text("Simple Text", style: TextStyle(fontSize: 18));

    // Simple expandable text
    final simpleExpandableTextTitle = Text("Simple Expandable Text", style: TextStyle(fontSize: 18));

    // Mention text
    final mentionTextTitle = Text("Mention Text", style: TextStyle(fontSize: 18));

    // Hashtag text
    final hashtagTextTitle = Text("Hashtag Text", style: TextStyle(fontSize: 18));

    // URL text
    final urlTextTitle = Text("URL Text", style: TextStyle(fontSize: 18));

    // Custom tag text
    final customTagTitle = Text("Custom Tag Text", style: TextStyle(fontSize: 18));

    // Multiple custom tag text
    final multiCustomTagTitle = Text("Multiple Custom Tag Text", style: TextStyle(fontSize: 18));

    // All text
    final allTextTitle = Text("All Text", style: TextStyle(fontSize: 18));

    // Programmatically handle text toggle
    final programmaticallyHandleTitle = Text("Programmatically Handle Toggle", style: TextStyle(fontSize: 18));

    /// A text to collapse and expand programmatically
    final programmaticExpandableRichText = ExpandableRichText(
      "这是一个可以通过编程方式展开和收起的文本。",
      controller: ExpandableRichTextController(),
      expandText: '展开',
      collapseText: '收起',
    );

    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: ListView(
        padding: const EdgeInsets.all(20),
        shrinkWrap: true,
        children: [
          simpleTextTitle,
          titleMargin,
          const ExpandableRichText("这是一段简单的文本。"),
          verticalMargin,
          simpleExpandableTextTitle,
          titleMargin,
          ExpandableRichText(
            "这是一段可以展开和收起的简单文本。",
            expandText: '展开',
            collapseText: '收起',
            toggleTextStyle: TextStyle(color: Colors.blue, decoration: TextDecoration.underline),
          ),
          verticalMargin,
          mentionTextTitle,
          titleMargin,
          ExpandableRichText(
            "@用户 这里有一个提及。",
            expandText: '展开',
            collapseText: '收起',
            toggleTextStyle: TextStyle(color: Colors.blue, decoration: TextDecoration.underline),
            mentionStyle: TextStyle(color: Colors.blueAccent, fontSize: 16, fontWeight: FontWeight.bold),
          ),
          verticalMargin,
          hashtagTextTitle,
          titleMargin,
          ExpandableRichText(
            "#话题 这里有一个话题。",
            expandText: '展开',
            collapseText: '收起',
            toggleTextStyle: TextStyle(color: Colors.blue, decoration: TextDecoration.underline),
            hashtagStyle: TextStyle(fontSize: 16, color: Colors.white, backgroundColor: Colors.black87),
          ),
          verticalMargin,
          urlTextTitle,
          titleMargin,
          ExpandableRichText(
            "www.example.com",
            expandText: '展开',
            collapseText: '收起',
            toggleTextStyle: TextStyle(color: Colors.blue, decoration: TextDecoration.underline),
            urlStyle: TextStyle(color: Colors.lightBlueAccent, decoration: TextDecoration.underline),
          ),
          verticalMargin,
          customTagTitle,
          titleMargin,
          ExpandableRichText(
            "<tag>自定义标签</tag>",
            expandText: '展开',
            collapseText: '收起',
            toggleTextStyle: TextStyle(color: Colors.blue, decoration: TextDecoration.underline),
            customTagStyle: TextStyle(fontWeight: FontWeight.bold, fontStyle: FontStyle.italic, fontSize: 16, color: Colors.white, backgroundColor: Colors.lightBlueAccent, decoration: TextDecoration.underline),
          ),
          verticalMargin,
          multiCustomTagTitle,
          titleMargin,
          ExpandableRichText(
            "<tag1>自定义标签1</tag1> <tag2>自定义标签2</tag2>",
            expandText: '展开',
            collapseText: '收起',
            toggleTextStyle: TextStyle(color: Colors.blue, decoration: TextDecoration.underline),
            customTagStyles: {
              'tag1': TextStyle(fontWeight: FontWeight.bold, fontSize: 16, color: Colors.red),
              'tag2': TextStyle(fontWeight: FontWeight.bold, fontSize: 16, color: Colors.green),
            },
          ),
          verticalMargin,
          allTextTitle,
          titleMargin,
          ExpandableRichText(
            "这是一段包含 @用户, #话题, 和 <tag>自定义标签</tag> 的文本。",
            expandText: '展开',
            collapseText: '收起',
            toggleTextStyle: TextStyle(color: Colors.blue, decoration: TextDecoration.underline),
            mentionStyle: TextStyle(color: Colors.blueAccent, fontSize: 16, fontWeight: FontWeight.bold),
            hashtagStyle: TextStyle(fontSize: 16, color: Colors.white, backgroundColor: Colors.black87),
            customTagStyle: TextStyle(fontWeight: FontWeight.bold, fontStyle: FontStyle.italic, fontSize: 16, color: Colors.white, backgroundColor: Colors.lightBlueAccent, decoration: TextDecoration.underline),
          ),
          verticalMargin,
          programmaticallyHandleTitle,
          titleMargin,
          Align(
            alignment: Alignment.topLeft,
            child: ElevatedButton(
              onPressed: () => programmaticExpandableRichText.controller?.toggleText(),
              child: const Text("Toggle"),
            ),
          ),
          titleMargin,
          programmaticExpandableRichText
        ],
      ),
    );
  }
}

通过上述代码,你可以看到如何创建一个包含不同类型的富文本内容的应用程序,并且展示了如何通过编程方式控制文本的展开和收起。希望这能帮助你在项目中更好地使用expandable_richtext插件!


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

1 回复

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


当然,下面是一个关于如何使用 expandable_richtext 插件在 Flutter 中实现富文本扩展的示例代码。这个插件允许你在富文本中嵌入可扩展的文本块,用户可以通过点击来展开或收起这些文本块。

首先,确保你已经在 pubspec.yaml 文件中添加了 expandable_richtext 依赖:

dependencies:
  flutter:
    sdk: flutter
  expandable_richtext: ^x.y.z  # 请替换为最新版本号

然后,运行 flutter pub get 来获取依赖。

接下来是一个完整的示例代码,展示如何使用 expandable_richtext

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Expandable RichText Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatelessWidget {
  final String expandableText =
      "This is an expandable text. Click the button below to see more content.";

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Expandable RichText Example'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: ExpandableRichText(
          // 初始展开状态
          initialExpandStatus: ExpandStatus.collapsed,
          // 展开按钮文本
          expandText: Text('Expand', style: TextStyle(color: Colors.blue)),
          // 收起按钮文本
          collapseText: Text('Collapse', style: TextStyle(color: Colors.blue)),
          // 富文本内容
          text: TextSpan(
            children: [
              TextSpan(text: 'This is a regular text. '),
              // 可扩展文本块
              ExpandableTextSpan(
                text: expandableText,
                // 可扩展文本样式
                style: TextStyle(color: Colors.black),
                // 点击事件回调(可选)
                onClick: () {
                  print('Expandable text clicked!');
                },
              ),
              TextSpan(text: ' This is another regular text after expandable text.'),
            ],
          ),
        ),
      ),
    );
  }
}

在这个示例中:

  1. ExpandableRichText 是主控件,它包含了整个可扩展的富文本内容。
  2. initialExpandStatus 属性决定了文本块初始是展开还是收起状态。
  3. expandTextcollapseText 属性分别定义了展开和收起按钮的文本和样式。
  4. text 属性是一个 TextSpan 对象,它定义了富文本的内容。在 TextSpan 的子元素中,我们使用了 ExpandableTextSpan 来嵌入可扩展的文本块。
  5. ExpandableTextSpantext 属性定义了可扩展文本的内容,style 属性定义了文本的样式,onClick 是一个可选的点击事件回调。

运行这个示例,你会看到一个包含可扩展文本块的富文本。点击“Expand”按钮可以展开文本块,点击“Collapse”按钮可以收起文本块。

回到顶部