用SpannableString显示表情

在app中,我们经常可以看到评论中带有表情(非emoji),如下图红色框处所示:


用SpannableString显示表情_第1张图片
某条评论中有很可爱的表情

这些表情是怎么实现的呢?
首先这些表情并不是emoji表情,是一些自定义的表情(也就是一些图片),通过解压apk文件,发现这些表情全部存放在apk安装包中,嗯。。。本地加载。。。

打印一下评论的接口,看看评论内容是个什么格式


图中第一个表情
图中第二个表情

可以看到,他是直接用[xxx]来表示评论字符串中的表情的。那问题就变成如何把评论中的[xxx]还原成表情就可以了。


首先,肯定有一个对应关系表,比如[大笑] 对应的大笑这张图片


用SpannableString显示表情_第2张图片
对应Map

有了原始的评论内容核对应Map,如何在文本中添加图片呢?看这里,大佬的文章解析的很清楚了:
用SpannableString打造绚丽多彩的文本显示效果

这里我们用到的是:ImageSpan由于很多地方会用到表情的转换,因此封装成一个工具类,直接上代码:

public class CommentEmojiUtil {
    private static Map 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("原始的评论字符串[大笑]"));
用SpannableString显示表情_第3张图片
效果图

完成~!

你可能感兴趣的:(用SpannableString显示表情)