flutter聊天界面-Text富文本表情emoji、url、号码展示

flutter聊天界面-Text富文本表情emoji、url、号码展示
Text富文本表情emoji展示,主要通过实现Text.rich展示文本、emoji、自定义表情、URL等
flutter聊天界面-Text富文本表情emoji、url、号码展示_第1张图片

一、Text及TextSpan

Text用于显示简单样式文本
TextSpan它代表文本的一个“片段”,不同“片段”可按照不同的样式显示。

示例片段

Text.rich(TextSpan(
    children: [
     TextSpan(
       text: "Home: "
     ),
     TextSpan(
       text: "https://flutterchina.club",
       style: TextStyle(
         color: Colors.blue
       ),  
       recognizer: _tapRecognizer
     ),
    ]
))

二、Text富文本表情emoji展示

Text富文本表情emoji展示主要通过RegExp匹配url、手机号码

自定义表情的正则表达式:

String emojExpString = r"\[.{1,4}?\]";

链接URL的正则表达式:

String urlExpString =
        r"(http|ftp|https)://([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?";

具体实现代码如下

// 富文本
class CommChatRichTextHelper {
  //图文混排
  static getRichText(String text) {
    List<InlineSpan> textSapns = [];

    String urlExpString =
        r"(http|ftp|https)://([\w_-]+(?:(?:\.[\w_-]+)+))([\w.,@?^=%&:/~+#-]*[\w@?^=%&/~+#-])?";
    String emojExpString = r"\[.{1,4}?\]";
    RegExp exp = RegExp('$urlExpString|$emojExpString');

    //正则表达式是否在字符串[input]中有匹配。
    if (exp.hasMatch(text)) {
      Iterable<RegExpMatch> matches = exp.allMatches(text);

      int index = 0;
      int count = 0;
      for (var matche in matches) {
        count++;
        String c = text.substring(matche.start, matche.end);
        //匹配到的东西,如表情在首位
        if (index == matche.start) {
          index = matche.end;
        }
        //匹配到的东西,如表情不在首位
        else if (index < matche.start) {
          String leftStr = text.substring(index, matche.start);
          index = matche.end;
          textSapns.add(
            TextSpan(
              text: spaceWord(leftStr),
              style: getDefaultTextStyle(),
            ),
          );
        }

        //匹配到的网址
        if (RegExp(urlExpString).hasMatch(c)) {
          textSapns.add(
            TextSpan(
              text: spaceWord(c),
              style:
                  TextStyle(color: ColorUtil.hexColor(0x3b93ff), fontSize: 16),
              recognizer: TapGestureRecognizer()
                ..onTap = () async {
                  //打开浏览器
                  print(c);
                },
            ),
          );
        }
        //匹配到的表情
        else if (RegExp(emojExpString).hasMatch(c)) {
          //[偷笑] 去掉[] = 偷笑
          String emojiString = c;
          textSapns.add(
            WidgetSpan(
              style: const TextStyle(height: 1.5),
              //判断表情是否存在
              child: CommonChatEmoji.emojiIsContain(emojiString)
                  ? ImageHelper.imageNetwork(
                      imageUrl:
                          "${CommonChatEmoji.findEmojiItem(emojiString)?.url}",
                      width: 22,
                      height: 22,
                    )
                  : Text(
                      "${c}",
                      style: getDefaultTextStyle(),
                    ),
            ),
          );
        }

        //是否是最后一个表情,并且后面是否有字符串
        if (matches.length == count && text.length > index) {
          String rightStr = text.substring(index, text.length);
          textSapns.add(
            TextSpan(
              text: spaceWord(rightStr),
              style: getDefaultTextStyle(),
            ),
          );
        }
      }
    } else {
      textSapns.add(
        TextSpan(
          text: spaceWord(text),
          style: getDefaultTextStyle(),
        ),
      );
    }

    return Text.rich(TextSpan(children: textSapns));
  }

  static TextStyle getDefaultTextStyle() {
    return TextStyle(
      fontSize: 16,
      fontWeight: FontWeight.w400,
      fontStyle: FontStyle.normal,
      color: ColorUtil.hexColor(0x555555),
      decoration: TextDecoration.none,
    );
  }

  static String spaceWord(String text) {
    if (text.isEmpty) return text;
    String spaceWord = '';
    for (var element in text.runes) {
      spaceWord += String.fromCharCode(element);
      spaceWord += '\u200B';
    }
    return spaceWord;
  }
}

使用Text.rich的Widget的聊天文本气泡

class ChatCellTextElem extends StatefulWidget {
  const ChatCellTextElem({
    Key? key,
    required this.chatMessage,
  }) : super(key: key);

  final CommonChatMessage chatMessage;

  
  State<ChatCellTextElem> createState() => _ChatCellTextElemState();
}

class _ChatCellTextElemState extends State<ChatCellTextElem> {
  
  Widget build(BuildContext context) {
    return Container(
      padding: EdgeInsets.all(10.0),
      child: buildTextContent(),
    );
  }

  Widget buildTextContent() {
    // 富文本
    return CommChatRichTextHelper.getRichText("${widget.chatMessage.text ?? ""}");
  }
}

三、小结

flutter聊天界面-Text富文本表情emoji、url、号码展示,主要实现Text富文本表情emoji展示主要通过RegExp匹配url、手机号码等

学习记录,每天不停进步。

你可能感兴趣的:(flutter开发实战,flutter,flutter,flutter聊天界面,flutter富文本)