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

flutter聊天界面-Text富文本表情emoji、url、号码展示
Text富文本表情emoji展示,主要通过实现Text.rich展示文本、emoji、自定义表情、URL等
在这里插入图片描述

一、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、手机号码等

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/35878.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Matlab画等构造图

clc;clear;close all; data xlsread(TOPBRENT等T0构造.xlsx); x data(:,1) xmax max(x); xmin min(x); y data(:,2) ymax max(y); ymin min(y); z data(:,3); N 45; …

IDEA使用插件绘制UML类图+PlantUML语法讲解

安装 IDEA安装插件 安装完插件记得重启一下IDEA 安装Graphviz&#xff08;亲测win11可以使用&#xff09; 安装完插件之后&#xff0c;还需要安装Graphviz才可以渲染图形。 Graphviz安装包下载地址 安装过程很简单&#xff0c;直接双击或者管理员身份运行即可&#xff0c;注…

Docker中部署Redis集群与部署微服务项目的详细过程

目录 一、使用Docker部署的好处二、Docker 与 Kubernetes 对比三、Redis集群部署实战四、Spring Boot项目 打包镜像?小结 一、使用Docker部署的好处 Docker的好处在于&#xff1a;在不同实例上运行相同的容器 Docker的五大优点&#xff1a; 持续部署与测试、多云服务平台支…

微信小程序开发与应用——字体样式设置

要求&#xff1a;设置字体样式。 1、打开微信开发者工具&#xff0c;创建一个小程序&#xff0c;如下&#xff1a; 2、设置小程序的项目名称和路径&#xff0c;并选择开发语言为JavaScript&#xff0c;如下&#xff1a; 3、小程序的主体部分由三个文件组成&#xff0c;且都要…

VS2019+Qt5.15 在线显示百度地图

1.Qt5.15编译程序需要选择mscv2019 Release版本 2.需要到百度地图开发平台注册并获取到开发者key 3.显示地图是JS与Qt的交互过程&#xff0c;显示地图的html文件&#xff1a; <!DOCTYPE html> <html><head> <meta name"viewport" content&q…

基于ubuntu的驱动开发

一般的linux驱动开发都是基于交叉编译来进行的&#xff0c;本文尝试着从另一个角度&#xff1a;基于ubuntu的本地驱动开发来学习一下驱动的开发 一、驱动的开发与编译 1.1、编写驱动文件 #include <linux/init.h> #include <linux/module.h> static int hello_i…

深入理解Linux网络——内核是如何接收到网络包的

文章目录 一、相关实际问题二、数据是如何从网卡到协议栈的1、Linux网络收包总览2、Linux启动1&#xff09;创建ksotfirqd内核线程2&#xff09;网络子系统初始化3&#xff09;协议栈注册4&#xff09;网卡驱动初始化5&#xff09;网卡启动 3、迎接数据的到来1&#xff09;硬中…

Gradio库中的Model3D模块:实时上传和展示3D模型

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

结合具体场景举例说明chatgpt预训练模型中Tokenization的原理

假设我们有一个场景&#xff0c;Alice想向Chatbot询问一部电影的推荐。她发送了一条消息&#xff1a;“你好&#xff0c;能给我推荐一部好看的电影吗&#xff1f;” 在这个场景中&#xff0c;Chatbot使用了ChatGPT预训练模型。首先&#xff0c;Chatbot需要对Alice的消息进行Tok…

OpenCV读取一张8位无符号三通道图像并显示

#include <iostream> #include <opencv2/imgcodecs.hpp> #include <opencv2/opencv.hpp> #include

c++编写网络爬虫

c爬虫项目 实现图形化界面UI 安装easyX&#xff08;需要用的graphisc.h&#xff09; 我之前的文章详细写到过如何安装。是这篇文章提到的&#xff1a;传送门 easyx官网 创建图形化界面 #define WINDOW_WIDTH 482 #define WINDOW_HEIGHT 300 void initUI() {initgraph(WINDO…

SwiftUI的优缺点

2019年WWDC大会上&#xff0c;苹果在压轴环节向大众宣布了基于Swift语言构建的全新UI框架——SwiftUI&#xff0c;开发者可通过它快速为所有的Apple平台创建美观、动态的应用程序。推荐大量使用struct代替类。 SwiftUI 就是⼀种声明式的构建界面的用户接口工具包。 SwiftUI使用…

机器学习与深度学习——自定义函数进行线性回归模型

机器学习与深度学习——自定义函数进行线性回归模型 目的与要求 1、通过自定义函数进行线性回归模型对boston数据集前两个维度的数据进行模型训练并画出SSE和Epoch曲线图&#xff0c;画出真实值和预测值的散点图&#xff0c;最后进行二维和三维度可视化展示数据区域。 2、通过…

SpringBoot + Vue前后端分离项目实战 || 五:用户管理功能后续

系列文章&#xff1a; SpringBoot Vue前后端分离项目实战 || 一&#xff1a;Vue前端设计 SpringBoot Vue前后端分离项目实战 || 二&#xff1a;Spring Boot后端与数据库连接 SpringBoot Vue前后端分离项目实战 || 三&#xff1a;Spring Boot后端与Vue前端连接 SpringBoot V…

企业内部安全:利用 ADAudit Plus 管理与加强安全审计

在现代数字化时代&#xff0c;企业面临着日益复杂和不断变化的安全威胁。为了保护敏感数据、遵守合规要求以及防范内部威胁&#xff0c;企业需要有效的安全审计解决方案。ADAudit Plus 是一款强大而全面的安全审计工具&#xff0c;可以帮助企业管理和加强内部安全。 ADAudit Pl…

Jenkins持续集成,在Linux中安装最新版Jenkins(详细)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 去年从6月28日发布…

git学习1

打标签 与其他版本控制系统&#xff08;VCS&#xff09;一样&#xff0c;Git 可以给仓库历史中的某一个提交打上标签&#xff0c;以示重要。 比较有代表性的是人们会使用这个功能来标记发布结点&#xff08; v1.0 、 v2.0 等等&#xff09;。 列出标签 在 Git 中列出已有的…

SpringCloud:微服务技术

一、认识微服务&#xff1a; 首先&#xff0c;微服务架构不等于SpringCloud&#xff0c;微服务架构是一种经过良好架构设计的分布式架构方案&#xff0c; &#xff0c;它将应用构建成一系列按业务领域划分模块的&#xff0c;小的自治服务&#xff0c;并解决服务拆分所产生的各种…

github搜索技巧笔记

一、了解 GitHub Watch按钮 Watch可以理解为关注的意思&#xff0c;默认情况下是Not watching&#xff0c;当选择Watch后&#xff0c;你会收到这个GitHub项目的所有动态。比如&#xff1a;有人发起pull request或者issue等。接收动态方式包括个人通知中心或者邮箱。 如果某个…

GIT版本控制常规性操作演示汇总

文章目录 GIT基本操作GIT配置个人信息配置&#xff1a;GIT查看个人信息配置&#xff1a;GIT的三大区域GIT回滚&#xff1a;git resetGIT恢复日志&#xff1a;git reflogGIT三大区域转换GIT新建分支GIT合并分支GIT删除分支码云上创建项目GIT变基&#xff1a;git rebase合并提交记…