用SpannableString显示表情
2018-03-12 本文已影响0人
言吾許
在app中,我们经常可以看到评论中带有表情(非emoji),如下图红色框处所示:
某条评论中有很可爱的表情
这些表情是怎么实现的呢?
首先这些表情并不是emoji表情,是一些自定义的表情(也就是一些图片),通过解压apk文件,发现这些表情全部存放在apk安装包中,嗯。。。本地加载。。。
打印一下评论的接口,看看评论内容是个什么格式
图中第一个表情 图中第二个表情
可以看到,他是直接用[xxx]来表示评论字符串中的表情的。那问题就变成如何把评论中的[xxx]还原成表情就可以了。
首先,肯定有一个对应关系表,比如[大笑] 对应的大笑这张图片
对应Map
有了原始的评论内容核对应Map,如何在文本中添加图片呢?看这里,大佬的文章解析的很清楚了:
用SpannableString打造绚丽多彩的文本显示效果
这里我们用到的是:ImageSpan
由于很多地方会用到表情的转换,因此封装成一个工具类,直接上代码:
public class CommentEmojiUtil {
private static Map<String, Integer> emojiMap;
/**
* 判断表情的正则表达式 [中英文]
*/
private static final String EMOJI = "\\[[\\u4e00-\\u9fa5a-zA-Z]+]";
/**
* 获取含有表情的spannableString
*
* @param commentString 服务器传过来的原始string
* @return 处理过的string
*/
public static SpannableString getEmojiString(String commentString) {
SpannableString spannableString = new SpannableString(commentString);
Pattern pattern = Pattern.compile(EMOJI);
Matcher matcher = pattern.matcher(spannableString);
boolean result = matcher.find();
//循环直到匹配不到
while (result) {
//matcher.group():匹配到的字符串,作为key,获取对应的图片
Drawable drawable = ContextCompat.getDrawable(MyApplication.getContext(), emojiMap.get(matcher.group()));
drawable.setBounds(0, 0, 42, 42);
ImageSpan imageSpan = new ImageSpan(drawable);
//matcher.start() matcher.end()是匹配到的字符串在原始字符串中的起始位置,进行替换
spannableString.setSpan(imageSpan, matcher.start(), matcher.end(), Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
result = matcher.find();
}
return spannableString;
}
static {
emojiMap = new HashMap<>();
//第一页
emojiMap.put("[捂脸]", R.mipmap.emoji1_1_1);
emojiMap.put("[大笑]", R.mipmap.emoji1_1_2);
emojiMap.put("[呲牙]", R.mipmap.emoji1_1_3);
emojiMap.put("[爱慕]", R.mipmap.emoji1_1_4);
emojiMap.put("[流泪]", R.mipmap.emoji1_1_5);
emojiMap.put("[害羞]", R.mipmap.emoji1_1_6);
emojiMap.put("[灵光一闪]", R.mipmap.emoji1_1_7);
......其他图片
}
}
直接在setText中调用写好的工具类
tvComment.setText(CommentEmojiUtil.getEmojiString("原始的评论字符串[大笑]"));
效果图
完成~!