搜索插件、代码仓与 APP 分类

插件详情v0.1.0

span_builder

从纯文本创建跨度并提供手势识别器的自动释放

近 30 天下载
11
喜欢数
18
Pub 分数
40

安装插件

flutter pub add span_builder

插件介绍

基于插件公开信息、社区数据与项目使用情况整理的选型参考。

SpanBuilder 是一个 Flutter/Dart 包,旨在简化从纯文本创建富文本段落的过程,便于集成样式化文本、链接和交互元素。它会自动管理 GestureRecognizers 的释放,防止内存泄漏并提升性能。适用于包含嵌入式交互的动态文本渲染,例如可点击的标签或提及。该包支持简洁的声明式语法,用于构建复杂的文本布局,而无需手动管理生命周期。

适合场景

  • 使用可点击元素构建交互式富文本
  • 使用混合样式渲染格式化文本
  • 创建提及或标签解析器
  • 自动清理手势识别器
  • 显示带有嵌入式操作的动态内容

主要特点

  • 自动释放 GestureRecognizer
  • 从纯文本创建简单跨度
  • 支持富文本样式
  • 减少样板代码
  • 防止内存泄漏

适合对象

  • 开发聊天界面的开发者
  • 动态文本内容的应用
  • 需要交互式文本元素的项目
  • 注重代码整洁性和可维护性的团队

使用建议

  • 限于基于文本的UI组件
  • 无内置的复杂布局支持
  • 需要理解 TextSpan 结构
  • 不适合非文本渲染需求
  • 依赖于 Flutter 的 Text widget 生态系统

原始 README

以下为关联源码仓库的 README 原文快照,最新内容请访问源码仓库。

span_builder

Facilitates creation of spans from plain text and provides an automated disposal of GestureRecognizers.

Description

Given some plain text, e.g.: "The quick brown fox" allows you to apply multiple spans at multiple positions. Positions can be specified by a matching word (whereText), e.g. "brown" and/or range from=10, to=15. Spans are subclasses of InlineSpan. If the span you are trying to apply is TextSpan you don't need to pass whereText as it will be inferred from text within the provided span.

Once you are done using SpanBuilder, use build() to return calculated list of spans. Spans can't overlap.

Usage:
final spans = SpanBuilder("The quick brown fox")
  .apply(TextSpan(text: "brown", style: TextStyle(fontWeight: FontWeight.bold)))
  .apply(TextSpan(text: "🦊"), whereText: "fox")
  .build()

From there you can use these spans in your RichText, e.g.:

RichText(
  text: TextSpan(children: spans)
)

If you plan to make your text "tappable" read on.

Handling GestrueRecognizer (text taps)

If you try passing GestrueRecognizer as a field in TextSpan it will get stripped away - HERE IS WHY.

TL;DR: We don't want to leak GestureRecognizer but TextSpan has no idea about the lifecycle of Widget so you need a stateful widget to keep a reference to the recognizer untill you're done with it. Sounds like a mess, right?

The workaround is to provide a builder for the recognizer like this:

apply(TextSpan(text: "jumps"),
  recognizerBuilder: () => TapGestureRecognizer()..onTap = () {
    // your code here
  })

Then you can use this SpanBuilder together with SpanBuilderWidget which will manage creating and disposing of TapGestrueRecognizer at the right time:

SpanBuilderWidget(
  text: SpanBuilder("fox jumps")
    ..apply(TextSpan(text: "jumps"),
      recognizerBuilder: () => TapGestureRecognizer()..onTap = () {
        // your code here
      })
)

If you care only about onTap interaction you can use this API shortcut:

apply(TextSpan(text: "jumps"),
  onTap: () {
    // your code here
  }
)
Testing:

There are little resources on how to test RichText in general. For this reason there is helper testing library span_builder_test that can help you verify state of your spans in your UI tests.

void main() {
  testWidgets('MyApp test', (WidgetTester tester) async {
    await tester.pumpWidget(MyApp());

    final spanFinder = find.byKey(span_key);

    expect(spanFinder, findsOneWidget);
    final allSpans = tester.findSpans(spanFinder).length;
    expect(allSpans, 8);

    final foxSpans = tester.findSpans(spanFinder, predicate: (span) {
      return span is TextSpan && span.text == "🦊"; 
    });
    expect(foxSpans.length, 1);
  });
}

span_builder_test

WidgetTest helpers and extensions for testing span_builder

Getting Started

This is a companion library to the span_builder library intended to help you write test wherever that library is used.

Usage
Related Content

所属分类

源码仓库

使用此插件的项目

暂无相关数据。