extended_text 0.2.6

  • README.md
  • CHANGELOG.md
  • Example
  • Installing
  • Versions
  • new54

extended_text #

pub package

extended official text to quickly build special text like inline image or @somebody,it also provide custom background,custom over flow.

Chinese bolg inline image

Speical text #

extended text helps you to build speical text quickly.

for example, follwing code show how to create @xxxx in your text.

you just to extend SpecialText and define your rule.

class AtText extends SpecialText {
  static const String flag = "@";
  AtText(TextStyle textStyle, SpecialTextGestureTapCallback onTap)
      : super(flag, " ", textStyle, onTap: onTap);

  @override
  TextSpan finishText() {
    // TODO: implement finishText

    final String atText = toString();
    return TextSpan(
        text: atText,
        style: textStyle?.copyWith(color: Colors.blue, fontSize: 16.0),
        recognizer: TapGestureRecognizer()
          ..onTap = () {
            if (onTap != null) onTap(atText);
          });
  }
}

and create your SpecialTextSpanBuilder by extend SpecialTextSpanBuilder

class MySpecialTextSpanBuilder extends SpecialTextSpanBuilder {
  @override
  TextSpan build(String data,
      {TextStyle textStyle, SpecialTextGestureTapCallback onTap}) {
    if (data == null || data == "") return null;
    List<TextSpan> inlineList = new List<TextSpan>();
    if (data != null && data.length > 0) {
      SpecialText specialText;
      String textStack = "";
      //String text
      for (int i = 0; i < data.length; i++) {
        String char = data[i];
        if (specialText != null) {
          if (!specialText.isEnd(char)) {
            specialText.appendContent(char);
          } else {
            inlineList.add(specialText.finishText());
            specialText = null;
          }
        } else {
          textStack += char;
          specialText =
              createSpecialText(textStack, textStyle: textStyle, onTap: onTap);
          if (specialText != null) {
            if (textStack.length - specialText.startFlag.length >= 0) {
              textStack = textStack.substring(
                  0, textStack.length - specialText.startFlag.length);
              if (textStack.length > 0) {
                inlineList.add(TextSpan(text: textStack, style: textStyle));
              }
            }
            textStack = "";
          }
        }
      }

      if (specialText != null) {
        inlineList.add(TextSpan(
            text: specialText.startFlag + specialText.getContent(),
            style: textStyle));
      } else if (textStack.length > 0) {
        inlineList.add(TextSpan(text: textStack, style: textStyle));
      }
    }

    // TODO: implement build
    return TextSpan(children: inlineList, style: textStyle);
  }

  @override
  SpecialText createSpecialText(String flag,
      {TextStyle textStyle, SpecialTextGestureTapCallback onTap}) {
    if (flag == null || flag == "") return null;
    // TODO: implement createSpecialText

    if (isStart(flag, AtText.flag)) {
      return AtText(textStyle, onTap);
    } else if (isStart(flag, EmojiText.flag)) {
      return EmojiText(textStyle);
    } else if (isStart(flag, DollarText.flag)) {
      return DollarText(textStyle, onTap);
    }
    return null;
  }
}

at last used them in extended text, import thing is that you can define your self rule to create your text span.

ExtendedText(
          "[love]Extended text help you to build rich text quickly. any special text you will have with extended text. "
              "\n\nIt's my pleasure to invite you to join \$FlutterCandies\$ if you want to improve flutter .[love]"
              "\n\nif you meet any problem, please let me konw @zmtzawqlp .[sun_glasses]",
          onSpecialTextTap: (String data) {
            if (data.startsWith("\$")) {
              launch("https://github.com/fluttercandies");
            } else if (data.startsWith("@")) {
              launch("mailto:zmtzawqlp@live.com");
            }
          },
          specialTextSpanBuilder: MySpecialTextSpanBuilder(),
          overflow: TextOverflow.ellipsis,
          //style: TextStyle(background: Paint()..color = Colors.red),
          maxLines: 10,
        ),

more detail

Inline-image #

to show your inline image, you just to use as follwing

ImageSpan(this.image,
      {@required this.imageWidth,
      @required this.imageHeight,
      this.margin,
      this.beforePaintImage,
      this.afterPaintImage,
      this.fit: BoxFit.scaleDown})

ImageSpan(AssetImage("xxx.jpg"),
          imageWidth: size,
          imageHeight: size,
          margin: EdgeInsets.only(left: 2.0, bottom: 0.0, right: 2.0));
    }

and you can also define your image by using beforePaintImage and afterPaintImage.

it's simple to create a loading placeholder.

ImageSpan(CachedNetworkImage(imageTestUrls.first), beforePaintImage:
                    (Canvas canvas, Rect rect, ImageSpan imageSpan) {
              bool hasPlaceholder = drawPlaceholder(canvas, rect, imageSpan);
              if (!hasPlaceholder) {
                clearRect(rect, canvas);
              }
              return false;
            },
                margin: EdgeInsets.only(right: 10.0),
                imageWidth: 80.0,
                imageHeight: 60.0),


bool drawPlaceholder(Canvas canvas, Rect rect, ImageSpan imageSpan) {
    bool hasPlaceholder = imageSpan.imageSpanResolver.imageInfo?.image == null;

    if (hasPlaceholder) {
      canvas.drawRect(rect, Paint()..color = Colors.grey);
      var textPainter = TextPainter(
          text: TextSpan(text: "loading", style: TextStyle(fontSize: 10.0)),
          textAlign: TextAlign.center,
          textScaleFactor: 1,
          textDirection: TextDirection.ltr,
          maxLines: 1)
        ..layout(maxWidth: rect.width);

      textPainter.paint(
          canvas,
          Offset(rect.left + (rect.width - textPainter.width) / 2.0,
              rect.top + (rect.height - textPainter.height) / 2.0));
    }
    return hasPlaceholder;
  }

  void clearRect(Rect rect, Canvas canvas) {
    ///if don't save layer
    ///BlendMode.clear will show black
    ///maybe this is bug for blendMode.clear
    canvas.saveLayer(rect, Paint());
    canvas.drawRect(rect, Paint()..blendMode = BlendMode.clear);
    canvas.restore();
  }

if you want cache the network image, you can use CachedNetworkImage and clear them with clearExtendedTextDiskCachedImages

 CachedNetworkImage(this.url,
      {this.scale = 1.0,
      this.headers,
      this.cache: false,
      this.retries = 3,
      this.timeLimit,
      this.timeRetry = const Duration(milliseconds: 100)})
      : assert(url != null),
        assert(scale != null);

/// 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> clearExtendedTextDiskCachedImages({Duration duration}) async

more detail

custom background (refer to issue 24335/24337 about background)

 BackgroundTextSpan(
                      text: "错误演示 12345",
                      background: Paint()..color = Colors.blue,
                    ),

and you can also to cilp your background with clipBorderRadius or paintBackground

clipBorderRadius: BorderRadius.all(Radius.circular(3.0)),
paintBackground: (BackgroundTextSpan backgroundTextSpan,
                          Canvas canvas,
                          Offset offset,
                          TextPainter painter,
                          Rect rect,
                          {Offset endOffset}) {}

more detail

custom overflow (refer to issue 26748)

you can define your custom over flow textspan with overFlowTextSpan.

          ExtendedText(...
             overFlowTextSpan: OverFlowTextSpan(children: <TextSpan>[
                      TextSpan(text: '  \u2026  '),
                      TextSpan(
                          text: "more detail",
                          style: TextStyle(
                            color: Colors.blue,
                          ),
                          recognizer: TapGestureRecognizer()
                            ..onTap = () {
                              launch(
                                  "https://github.com/fluttercandies/extended_text");
                            })
                    ], background: Theme.of(context).canvasColor),
                    ...
                  )

more detail

[0.2.6]

  • change BeforePaintImage function to BeforePaintTextImage change AfterPaintImage function to AfterPaintTextImage

[0.2.5]

  • fix issue that BackgroundTextSpan has error clip.

[0.2.4]

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

[0.2.2]

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

[0.2.1]

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

[0.1.8]

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

example/README.md

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:


dependencies:
  extended_text: ^0.2.6

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter packages get

Alternatively, your editor might support flutter packages 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.2.6 Mar 20, 2019 Go to the documentation of extended_text 0.2.6 Download extended_text 0.2.6 archive
0.2.5 Mar 18, 2019 Go to the documentation of extended_text 0.2.5 Download extended_text 0.2.5 archive
0.2.4 Mar 18, 2019 Go to the documentation of extended_text 0.2.4 Download extended_text 0.2.4 archive
0.2.3 Mar 18, 2019 Go to the documentation of extended_text 0.2.3 Download extended_text 0.2.3 archive
0.2.2 Mar 18, 2019 Go to the documentation of extended_text 0.2.2 Download extended_text 0.2.2 archive
0.2.1 Mar 18, 2019 Go to the documentation of extended_text 0.2.1 Download extended_text 0.2.1 archive
0.2.0 Mar 18, 2019 Go to the documentation of extended_text 0.2.0 Download extended_text 0.2.0 archive
0.1.9 Mar 18, 2019 Go to the documentation of extended_text 0.1.9 Download extended_text 0.1.9 archive
0.1.8 Mar 17, 2019 Go to the documentation of extended_text 0.1.8 Download extended_text 0.1.8 archive
0.1.7 Mar 17, 2019 Go to the documentation of extended_text 0.1.7 Download extended_text 0.1.7 archive

All 16 versions...

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

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

  • Dart: 2.2.0
  • pana: 0.12.14
  • Flutter: 1.3.3

Platforms

Detected platforms: Flutter

References Flutter, and has no conflicting libraries.

Dependencies

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