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、手机号码等
学习记录,每天不停进步。