Flutter 支持图片以及特殊文字的输入框(一)使用方法

栏目: Android · 发布时间: 5年前

内容简介:最近有客户Alex提出Flutter输入框需要支持支持图片和特殊文字样式,就跟QQ,微信,微博一样,可以插入表情,@xxx或者一个话题. 每天追更,每天都在群里@我(FlutterCandies QQ群:181398081),就差点就把他禁言了。但是我没有这样做,客户就是上帝,因为之前做过Extended Text,假装感觉应该很简单,悄悄在空闲的时候就动手做起来了。本篇只介绍下用法,下一篇再讲讲开发中的辛酸历程,先上效果图。

extended_text_field 相关文章

最近有客户Alex提出Flutter输入框需要支持支持图片和特殊文字样式,就跟QQ,微信,微博一样,可以插入表情,@xxx或者一个话题. 每天追更,每天都在群里@我(FlutterCandies QQ群:181398081),就差点就把他禁言了。但是我没有这样做,客户就是上帝,因为之前做过Extended Text,假装感觉应该很简单,悄悄在空闲的时候就动手做起来了。

Flutter 支持图片以及特殊文字的输入框(一)使用方法

本篇只介绍下用法,下一篇再讲讲开发中的辛酸历程,先上效果图。

Flutter 支持图片以及特殊文字的输入框(一)使用方法

使用步骤

  • 关注,点赞,转发,送飞机

  • 使用ExtendedTextField

  • Flutter Candies全家桶

关注,点赞,转发,送飞机

pub 搜索 extended_text_field

github 地址: extended_text_field

定义自己的特殊文字

Flutter 支持图片以及特殊文字的输入框(一)使用方法

比如表情

我这里定义的格式是比如[1],就代表是表情1(就是你对应的表情图片).

class EmojiText extends SpecialText {
  static const String flag = "[";
  final int start;
  EmojiText(TextStyle textStyle, {this.start})
      : super(EmojiText.flag, "]", textStyle);

  @override
  TextSpan finishText() {
    // TODO: implement finishText
    var key = toString();
    if (EmojiUitl.instance.emojiMap.containsKey(key)) {
      //fontsize id define image height
      //size = 30.0/26.0 * fontSize
      final double size = 20.0;

      ///fontSize 26 and text height =30.0
      //final double fontSize = 26.0;

      return ImageSpan(AssetImage(EmojiUitl.instance.emojiMap[key]),
          actualText: key,
          imageWidth: size,
          imageHeight: size,
          start: start,
          deleteAll: true,
          fit: BoxFit.fill,
          margin: EdgeInsets.only(left: 2.0, top: 2.0, right: 2.0));
    }

    return TextSpan(text: toString(), style: textStyle);
  }
}

class EmojiUitl {
  final Map<String, String> _emojiMap = new Map<String, String>();

  Map<String, String> get emojiMap => _emojiMap;

  final String _emojiFilePath = "assets";

  static EmojiUitl _instance;
  static EmojiUitl get instance {
    if (_instance == null) _instance = new EmojiUitl._();
    return _instance;
  }

  EmojiUitl._() {
    for (int i = 1; i < 49; i++) {
      _emojiMap["[$i]"] = "$_emojiFilePath/$i.png";
    }
  }
}
复制代码

再举一个

Flutter 支持图片以及特殊文字的输入框(一)使用方法

比如 @法的空间

以@为开始标志,空格为结束标志

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);

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

    final String atText = toString();

    if (type == BuilderType.extendedText)
      return TextSpan(
          text: atText,
          style: textStyle,
          recognizer: TapGestureRecognizer()
            ..onTap = () {
              if (onTap != null) onTap(atText);
            });

    return showAtBackground
        ? BackgroundTextSpan(
            background: Paint()..color = Colors.blue.withOpacity(0.15),
            text: atText,
            actualText: atText,
            start: start,
            deleteAll: false,
            style: textStyle,
            recognizer: type == BuilderType.extendedText
                ? (TapGestureRecognizer()
                  ..onTap = () {
                    if (onTap != null) onTap(atText);
                  })
                : null)
        : SpecialTextSpan(
            text: atText,
            actualText: atText,
            start: start,
            deleteAll: false,
            style: textStyle,
            recognizer: type == BuilderType.extendedText
                ? (TapGestureRecognizer()
                  ..onTap = () {
                    if (onTap != null) onTap(atText);
                  })
                : null);
  }
}
复制代码

定义文字解析帮助类

必须实现createSpecialText方法,这样才知道你有哪些特殊文字

一个是build的方法,可选实现。如果你自己实现了要注意,特殊TextSpan必须放在返回的TextSpan的children里面,我只会遍历这一层,不会再去查找children的children了。

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

  @override
  TextSpan build(String data, {TextStyle textStyle, onTap}) {
    // TODO: implement build
    var textSpan = super.build(data, textStyle: textStyle, onTap: onTap);
   //for performance, make sure your all SpecialTextSpan are only in textSpan.children
    //extended_text_field will only check SpecialTextSpan in textSpan.children
    return textSpan;
  }

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

    ///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;
  }
}

enum BuilderType { extendedText, extendedTextField }
复制代码

使用ExtendedTextField

是不是炒鸡简单,这样你的文字就会自动转换为对应的特殊文字类型了

ExtendedTextField(
            specialTextSpanBuilder: MySpecialTextSpanBuilder(
                showAtBackground: true, type: BuilderType.extendedTextField),
复制代码

限制

readme 上面讲的一样,有三种限制。

  • 不支持文字从右到左,也就是不支持TextDirection.rtl。原因是TextPainter 给的图片的位置,非常奇怪,完全没法搞。当然我会继续跟进,也许哪天官方修好了呢?
  • 不支持那种密码的输入样式解析成特殊TextSpan,也就是不支持obscureText 为true。没啥好解释,文字都变成******了,也没必要解析了。
  • 代码是基于flutter 版本1.5.7,可能在不同的flutter 版本下面会出现编译错误,如果出现,希望老板们能根据自己的版本进行更正。我这边不太可能都适配到每个flutter 版本,我会尽量让 extended_text_field 在flutter 的稳定版本上面没有错误,希望谅解。

最后放上 extended_text_field ,如果你有什么不明白或者对这个方案有什么改进的地方,请告诉我,欢迎加入 Flutter Candies ,一起生产可爱的Flutter 小糖果(QQ群:181398081)

Flutter Candies全家桶

最最后放上 Flutter Candies 全家桶,真香。

custom flutter candies(widgets) for you to easily build flutter app, enjoy it.

extended_nested_scroll_view

extended_image

extended_text

extended_text_field

pull_to_refresh_notification

loading_more_list

extended_tabs

http_client_helper

Flutter 支持图片以及特殊文字的输入框(一)使用方法

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Introduction to Linear Optimization

Introduction to Linear Optimization

Dimitris Bertsimas、John N. Tsitsiklis / Athena Scientific / 1997-02-01 / USD 89.00

"The true merit of this book, however, lies in its pedagogical qualities which are so impressive..." "Throughout the book, the authors make serious efforts to give geometric and intuitive explanations......一起来看看 《Introduction to Linear Optimization》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具