extended_text 0.5.8

  • README.md
  • Example
  • Installing
  • Versions
  • 88

extended_text #

pub package

Language: English | 中文简体

A powerful extended official text for Dart, which supports Speical Text(Image,@somebody), Custom Background, Custom overFlow, Text Selection.

Table of contents #

Speical Text #

Create Speical Text #

extended text helps to convert your text to speical textSpan quickly.

for example, follwing code show how to create @xxxx speical textSpan.

class AtText extends SpecialText {
  static const String flag = "@";
  final int start;

  /// whether show background for @somebody
  final bool showAtBackground;

  final BuilderType type;
  AtText(TextStyle textStyle, SpecialTextGestureTapCallback onTap,
      {this.showAtBackground: false, this.type, this.start})
      : super(flag, " ", textStyle, onTap: onTap);

  TextSpan finishText() {
    TextStyle textStyle =
        this.textStyle?.copyWith(color: Colors.blue, fontSize: 16.0);

    final String atText = toString();

    return showAtBackground
        ? BackgroundTextSpan(
            background: Paint()..color = Colors.blue.withOpacity(0.15),
            text: atText,
            actualText: atText,
            start: start,

            ///caret can move into special text
            deleteAll: true,
            style: textStyle,
            recognizer: type == BuilderType.extendedText
                ? (TapGestureRecognizer()
                  ..onTap = () {
                    if (onTap != null) onTap(atText);
                : null)
        : SpecialTextSpan(
            text: atText,
            actualText: atText,
            start: start,
            style: textStyle,
            recognizer: type == BuilderType.extendedText
                ? (TapGestureRecognizer()
                  ..onTap = () {
                    if (onTap != null) onTap(atText);
                : null);

SpecialTextSpanBuilder #

create your SpecialTextSpanBuilder

class MySpecialTextSpanBuilder extends SpecialTextSpanBuilder {
  /// whether show background for @somebody
  final bool showAtBackground;
  final BuilderType type;
      {this.showAtBackground: false, this.type: BuilderType.extendedText});

  TextSpan build(String data, {TextStyle textStyle, onTap}) {
    var textSpan = super.build(data, textStyle: textStyle, onTap: onTap);
    return textSpan;

  SpecialText createSpecialText(String flag,
      {TextStyle textStyle, SpecialTextGestureTapCallback onTap, int index}) {
    if (flag == null || flag == "") return null;

    ///index is end index of start flag, so text start index should be index-(flag.length-1)
    if (isStart(flag, AtText.flag)) {
      return AtText(textStyle, onTap,
          start: index - (AtText.flag.length - 1),
          showAtBackground: showAtBackground,
          type: type);
    } else if (isStart(flag, EmojiText.flag)) {
      return EmojiText(textStyle, start: index - (EmojiText.flag.length - 1));
    } else if (isStart(flag, DollarText.flag)) {
      return DollarText(textStyle, onTap,
          start: index - (DollarText.flag.length - 1), type: type);
    return null;

more detail

Image #

ImageSpan #

show image in text by using ImageSpan

  this.image, {
  @required this.imageWidth,
  @required this.imageHeight,
  this.fit: BoxFit.scaleDown,
  String actualText: imageSpanTransparentPlaceholder,
  int start: 0,
  this.clearMemoryCacheIfFailed: true,
  GestureRecognizer recognizer,

        imageWidth: size,
        imageHeight: size,
        margin: EdgeInsets.only(left: 2.0, bottom: 0.0, right: 2.0));
imageThe image to display(ImageProvider).-
imageWidthThe width of image(not include margin)required
imageHeightThe height of image(not include margin)required
marginThe margin of image-
beforePaintImageYou can paint your placeholder or clip etc if needed-
afterPaintImageYou can paint border,shadow etc if needed-
actualTextActual text, take care of it when enable selection,something likes "[love]""\u200B"
startStart index of text,take care of it when enable selection.0
clearMemoryCacheIfFailedWhen failed to load image, whether clear memory cache,if ture, image will reload in next time.true
recognizerA gesture recognizer that will receive events that hit this text span.-

Cache Image #

if you want cache the network image, you can use ExtendedNetworkImageProvider and clear them with clearDiskCachedImages

  this.url, {
  this.scale = 1.0,
  this.cache: false,
  this.retries = 3,
  this.timeRetry = const Duration(milliseconds: 100),
  CancellationToken cancelToken,
})  : assert(url != null),
      assert(scale != null),
      cancelToken = cancelToken ?? CancellationToken();
urlThe URL from which the image will be fetched.required
scaleThe scale to place in the [ImageInfo] object of the image.1.0
headersThe HTTP headers that will be used with [HttpClient.get] to fetch image from network.-
cachewhether cache image to localfalse
retriesthe time to retry to request3
timeLimittime limit to request image-
timeRetrythe time duration to retry to requestmilliseconds: 100
cancelTokentoken to cancel network requestCancellationToken()
/// Clear the disk cache directory then return if it succeed.
///  <param name="duration">timespan to compute whether file has expired or not</param>
Future<bool> clearDiskCachedImages({Duration duration}) async

more detail

Selection #

selectionEnabledWhether enable selectionfalse
selectionColorColor of selectionTheme.of(context).textSelectionColor
dragStartBehaviorDragStartBehavior for text selectionDragStartBehavior.start
textSelectionControlsAn interface for building the selection UI, to be provided by the implementor of the toolbar widget or handle widgetextendedMaterialTextSelectionControls/extendedCupertinoTextSelectionControls

TextSelectionControls #

default value of textSelectionControls are extendedMaterialTextSelectionControls/extendedCupertinoTextSelectionControls

override buildToolbar or buildHandle to custom your toolbar widget or handle widget

class MyExtendedMaterialTextSelectionControls
    extends ExtendedMaterialTextSelectionControls {
  Widget buildToolbar(BuildContext context, Rect globalEditableRegion,
      Offset position, TextSelectionDelegate delegate) {
    return ConstrainedBox(
      constraints: BoxConstraints.tight(globalEditableRegion.size),
      child: CustomSingleChildLayout(
        delegate: ExtendedTextSelectionToolbarLayout(
        child: _TextSelectionToolbar(
          handleCopy: canCopy(delegate) ? () => handleCopy(delegate) : null,
              canSelectAll(delegate) ? () => handleSelectAll(delegate) : null,
          handleLike: () {
            //mailto:<email address>?subject=<subject>&body=<body>, e.g.

/// Manages a copy/paste text selection toolbar.
class _TextSelectionToolbar extends StatelessWidget {
  const _TextSelectionToolbar(
      {Key key, this.handleCopy, this.handleSelectAll, this.handleLike})
      : super(key: key);

  final VoidCallback handleCopy;
  final VoidCallback handleSelectAll;
  final VoidCallback handleLike;

  Widget build(BuildContext context) {
    final List<Widget> items = <Widget>[];
    final MaterialLocalizations localizations =

    if (handleCopy != null)
          child: Text(localizations.copyButtonLabel), onPressed: handleCopy));
    if (handleSelectAll != null)
          child: Text(localizations.selectAllButtonLabel),
          onPressed: handleSelectAll));
    if (handleLike != null)
      items.add(FlatButton(child: Icon(Icons.favorite), onPressed: handleLike));

    return Material(
      elevation: 1.0,
      child: Container(
        height: 44.0,
        child: Row(mainAxisSize: MainAxisSize.min, children: items),

Control ToolBar Handle #

contain your page into ExtendedTextSelectionPointerHandler, so you can control toolbar and handle.

Default Behavior #

set your page as child of ExtendedTextSelectionPointerHandler

 return ExtendedTextSelectionPointerHandler(
      //default behavior
       child: result,
  • tap region outside of extended text, hide toolbar and handle
  • scorll, hide toolbar and handle

Custom Behavior #

get selectionStates(ExtendedTextSelectionState) by builder call back, and handle by your self.

 return ExtendedTextSelectionPointerHandler(
      //default behavior
      // child: result,
      //custom your behavior
      builder: (states) {
        return Listener(
          child: result,
          behavior: HitTestBehavior.translucent,
          onPointerDown: (value) {
            for (var state in states) {
              if (!state.containsPosition(value.position)) {
                //clear other selection
          onPointerMove: (value) {
            //clear other selection
            for (var state in states) {

more detail

Custom Background #

refer to issues 24335/24337 about background

          "This text has nice background with borderradius,no mattter how many line,it likes nice",
      background: Paint()..color = Colors.indigo,
      clipBorderRadius: BorderRadius.all(Radius.circular(3.0))),
backgroundBackground painter-
clipBorderRadiusClip BorderRadius-
paintBackgroundPaint background call back, you can paint background by self-

more detail

Custom Overflow #

refer to issue 26748

      overFlowTextSpan: OverFlowTextSpan(children: <TextSpan>[
              TextSpan(text: '  \u2026  '),
                  text: "more detail",
                  style: TextStyle(
                    color: Colors.blue,
                  recognizer: TapGestureRecognizer()
                    ..onTap = () {

more detail


  • Breaking change: Remove background parameter of [OverFlowTextSpan]


  • Issue: Fix textEditingValue and textSelectionControls are not update when didUpdateWidget


  • Feature: Support text selection
  • Issue: Fix issue about rect of overFlowTextSpan


  • Update extended_text_library


  • Update path_provider 1.1.0


  • Update extended_text_library Remove caretIn parameter(SpecialTextSpan) DeleteAll parameter has the same effect as caretIn parameter(SpecialTextSpan)


  • Fix wrong background rect of OverFlowTextSpan when over flow area has image span


  • Fix wrong background rect of OverFlowTextSpan(issue 6)


  • Disabled informationCollector to keep backwards compatibility for now (ExtendedNetworkImageProvider)


  • Add GestureRecognizer for ImageSpan
  • Add demo to show image in photo view


  • Handle image span load failed


  • Update extended_text_library for cache folder is changed


  • Update extended_text_library for BackgroundTextSpan


  • Override compareTo method in BackgroundTextSpan and OverFlowTextSpan to Fix issue that it was error rendering


  • Import extended_text_library


  • Fix issue that tap exception throw when use OverFlowTextSpan


  • Add clearFailedCache parameter for CachedNetworkImage Add clearLoadFailedImageMemoryCache method Both them are used to clear image load failed memory cache, so that image will be reloaded


  • Update path_provider version from 0.4.1 to 0.5.0+1


  • Change SpecialTextGestureTapCallback input from string to dynamic


  • Change BeforePaintImage function to BeforePaintTextImage Change AfterPaintImage function to AfterPaintTextImage


  • Fix issue that BackgroundTextSpan has error clip.


  • Add TextPainter wholeTextPainter for BackgroundTextSpan's paintBackground call back,so that you can get info for whole text painter.


  • Fix issue that find TextPosition near overflow is not accurate.


  • Use ExtendedTextOverflow to replace TextOverflow(new flutter sdk TextOverflow has new value TextOverflow.visible)


  • Suport inline image, custom background ,custom over flow.


example #

A new Flutter application.

Getting Started #

This project is a starting point for a Flutter application.

A few resources to get you started if this is your first Flutter project:

For help getting started with Flutter, view our online documentation, which offers tutorials, samples, guidance on mobile development, and a full API reference.

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:

  extended_text: ^0.5.8

2. Install it

You can install packages from the command line:

with Flutter:

$ flutter pub get

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:

import 'package:extended_text/extended_text.dart';
Version Uploaded Documentation Archive
0.5.8 Jun 18, 2019 Go to the documentation of extended_text 0.5.8 Download extended_text 0.5.8 archive
0.5.7 Jun 12, 2019 Go to the documentation of extended_text 0.5.7 Download extended_text 0.5.7 archive
0.5.6 Jun 12, 2019 Go to the documentation of extended_text 0.5.6 Download extended_text 0.5.6 archive
0.5.5 Jun 12, 2019 Go to the documentation of extended_text 0.5.5 Download extended_text 0.5.5 archive
0.5.4 Jun 11, 2019 Go to the documentation of extended_text 0.5.4 Download extended_text 0.5.4 archive
0.5.3 Jun 6, 2019 Go to the documentation of extended_text 0.5.3 Download extended_text 0.5.3 archive
0.5.2 May 30, 2019 Go to the documentation of extended_text 0.5.2 Download extended_text 0.5.2 archive
0.5.1 May 29, 2019 Go to the documentation of extended_text 0.5.1 Download extended_text 0.5.1 archive
0.5.0 May 18, 2019 Go to the documentation of extended_text 0.5.0 Download extended_text 0.5.0 archive
0.4.9 May 18, 2019 Go to the documentation of extended_text 0.4.9 Download extended_text 0.4.9 archive

All 47 versions...

Describes how popular the package is relative to other packages. [more]
Code health derived from static analysis. [more]
Reflects how tidy and up-to-date the package is. [more]
Weighted score of the above. [more]
Learn more about scoring.

We analyzed this package on Jun 26, 2019, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.3.2
  • pana: 0.12.18
  • Flutter: 1.5.4-hotfix.2


Detected platforms: Flutter

References Flutter, and has no conflicting libraries.

Maintenance issues and suggestions

Support latest dependencies. (-15 points)

The version constraint in pubspec.yaml does not support the latest published versions for 3 dependencies.


Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.1.0-dev.68.0 <3.0.0
extended_image_library ^0.1.3 0.1.3
extended_text_library ^0.4.1 0.4.1
flutter 0.0.0
Transitive dependencies
async 2.2.0
charcode 1.1.2
collection 1.14.11
convert 2.1.1
crypto 2.0.6
http 0.12.0+2
http_client_helper 0.1.9 0.2.0
http_parser 3.1.3
meta 1.1.6 1.1.7
path 1.6.2
path_provider 1.1.0
pedantic 1.7.0
sky_engine 0.0.99
source_span 1.5.5
string_scanner 1.0.4
term_glyph 1.1.0
transparent_image 0.1.0 1.0.0
typed_data 1.1.6
vector_math 2.0.8
Dev dependencies