吐槽:第一次写博客,新手一枚。写这个博客为了共享一下资源,大家相互学习,最主要目的是抛砖引玉,引大婶指高见。

前言:需求是这样的,搞聊天,而且是在一个字库里面没有emoji的android系统里面搞。我收到的数据格式是这样的“我是新来的< emoji1f639 >”、”我是新来的[微笑]”。其中< emoji1f639 >和[微笑]就是表情了,所以需要匹配里面的emoji表情和QQ表情。

首先是显示Emoji

(emoji说白了就是一套统一的Unicode编码,每一个编码索引一个emoji表情。emoji(えもじ)是岛国圣斗士发明的,会日语所以读起来很有感觉。)

效果图(我一般比较喜欢先看图再看码):

首先是判断是否有emoji在消息里面,因为emoji只需要替换消息的内容,所以首先处理。这里使用正则表达式来处理,判断是否满足条件,然后将匹配到的内容add到容器里面。

 private boolean checkEmojiInText(String text){if(text == null && text.equals(""))return false;//正则:取<emoji 和 >之间的内容(包含<emoji 和 >)Pattern p = Pattern.compile("<emoji(.*?)>");Matcher matcher = p.matcher(text);while (matcher.find()) {emojiTabList.add(matcher.group());}if(emojiTabList.size() > 0){return true;}return false;}

上面方法如果返回ture,就证明有emoji躲在text里面,所以我们需要找出来它的位置并把它给替换成emoji编码。
emoji字符串转成16进制的int就得到Unicode了,然后用 0x1F639 替换掉之前的< emoji1f639>就可以了。

if(checkEmojiInText(message)){for(int i = 0; i < emojiTabList.size(); i++){String emojiTab = emojiTabList.get(i).replace("<emoji", "").replace(">", "").toUpperCase();//string to 16进制 intint code = Integer.valueOf(emojiTab, 16);//转换成emojiString emoji = String.valueOf(Character.toChars(code));message = message.replace(emojiTabList.get(i), emoji);}LogUtils.i("new message is " + message);emojiTabList.clear();}

上面说了,我是在一个没有emoji表情的世界里玩emoji的,自然我就需要emoji的字库啦。千辛万苦找到了几套emoji font ttf,有ios的、htc的、三星等等,有性趣的朋友可以在下面下。

你想要emoji font ttf , 就点我把

使用方法的话,很简单就是在引用放在assets里面的字库,然后textview setTypeface就可以了。

Typeface typeface = Typeface.createFromAsset(mContext.getResources().getAssets(), "ColorEmojiFont.ttf");
textView.setTypeface(typeface );

然后到QQ表情

QQ表情的话,我是放在emoji之后才处理,因为emoji只是替换内容,QQ表情的话要用到
SpannableString,所以我放在后面处理。最终返回的结果是返回SpannableString,才能显示QQ表情。

SpannableString使用的话,给你一个跳板(某个大婶的博客)
Android开发之TextView高级应用

效果图(先看图再看码):

首先先判断是否有QQ表情在消息里面,这里继续用上正则表达式,判断’[’ 和’]’里面出现字符的个数。如果出现1~3个之间,证明有可能是表情。因为还不能准确地确定,所以把有一个结果add到容器里面先,然后再匹配。

private boolean checkFaceInText(String text){if(text == null && text.equals(""))return false;//正则:以[开头, 以]结尾,中间至少出现一个字符,但是不能超过三个Pattern p = Pattern.compile("\\[.{1,3}?\\]");Matcher matcher = p.matcher(text);while (matcher.find()) {faceTabList.add(matcher.group());facePositionList.add(matcher.start());}if(faceTabList.size() > 0&& facePositionList.size() > 0&& faceTabList.size() == facePositionList.size()){return true;}return false;}

接着做一个准备工作,就是在assets里面的face_icon文件夹内将所有QQ表情图片匹配到容器里面,这里我匹配到三个容器,为什么呢?因为我喜欢。

 public void prepareChatFace(){if(mContext == null)return;if(oneStringList.size() == 0 && twoStringList.size() == 0 && threeStringList.size() == 0){try {InputStream inputStream = mContext.getResources().getAssets().open(ASSETS_FACE_FILE);BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));String lineInfo = null;while ((lineInfo = bufferedReader.readLine()) != null) {String[] infoContent = lineInfo.split(",");FaceInfo faceInfo = new FaceInfo();faceInfo.setFaceName(infoContent[1]);faceInfo.setFaceResource(getImageFromAssetsFile(infoContent[0]));//face tag lenghtint strLenght = infoContent[1].length();switch (strLenght){case 1:oneStringList.add(faceInfo);break;case 2:twoStringList.add(faceInfo);break;case 3:threeStringList.add(faceInfo);break;default:break;}}} catch (IOException e) {LogUtils.e("get assets file exception. error: " + e.getMessage());e.printStackTrace();}LogUtils.i("prepare all chat face to assign list finish!");}}

这里有一个getImageFromAssetsFile 方法,是用来读取QQ表情的

private Bitmap getImageFromAssetsFile(String fileName) {if(mContext == null)return null;Bitmap image = null;AssetManager am = mContext.getResources().getAssets();try{InputStream is = am.open(ASSETS_FACE_RESOURCE_FLODER+ "/" + fileName + ".png");image = BitmapFactory.decodeStream(is);is.close();if(image != null){return image;}}catch (IOException e) {LogUtils.e("read face image exception, error: " + e.getMessage());e.printStackTrace();}return null;}

好啦好啦,继续继续。这里使用到SpannableString,将拿到的QQ表情放到ImageSpan里面,然后通过spannableString.setSpan把ImageSpan放到SpannableString里面,setSpan开始位置用indexOf得到,然后结束位置用开始位置加上分割出来的字符串长度就可以了。

//接着判断 faceSpannableString spannableString = new SpannableString(message);if(checkFaceInText(message)){//准备工作prepareChatFace();for (int i = 0; i < faceTabList.size(); i++) {Bitmap res = findRelevantFace(faceTabList.get(i).replace("[", "").replace("]", ""));if (res == null) continue;ImageSpan imageSpan = new ImageSpan(mContext, res);int startPos = facePositionList.get(i);int endPos = startPos + faceTabList.get(i).length();spannableString.setSpan(imageSpan, startPos, endPos,Spanned.SPAN_INCLUSIVE_INCLUSIVE);}faceTabList.clear();facePositionList.clear();}

这里有个findRelevantFace方法,作用是找到相应的QQ表情。

    private Bitmap findRelevantFace(String text){if(text == null && text.equals(""))return null;switch (text.length()){case 1:for(FaceInfo faceInfo : oneStringList){if(faceInfo.getFaceName().equals(text)){return faceInfo.getFaceResource();}}break;case 2:for(FaceInfo faceInfo : twoStringList){if(faceInfo.getFaceName().equals(text)){return faceInfo.getFaceResource();}}break;case 3:for(FaceInfo faceInfo : threeStringList){if(faceInfo.getFaceName().equals(text)){return faceInfo.getFaceResource();}}break;}return null;}

好啦这样就大功告成啦!!!

总结

第一次写文章,有点乱,望见谅。错误之处请指出,相互学习。
其实还是省略了很多的,有性趣的朋友可以download我的demo看看, 就是一个很简单的demo。
demo size有点大,是as的。

download demo

下面是github地址
demo

Android项目 匹配Text里面的Emoji 和 QQ表情相关推荐

  1. 关于新建android项目,MainActivity里面的onCreate()方法、R文件报错的解决方法

    做为一位刚刚上手Android开发的小白来说,要适应一门开发语言和一款开发工具十分费劲.本人也在摸索的路上走了很多的弯路,也有了一点点的经验和问题的解决方案,和大家分享一下. 这是关于第一次用Andr ...

  2. Android通过读取AndroidManifest里面的meta-data获取参数

    如题,在AndroidManifest里面的meta-data里面配置: <application><meta-dataandroid:name="TTAPPID" ...

  3. android module 引用libs里面的so文件_Android中的JNI开发,你了解多少?

    一,什么是任务及管理 任务是用户在执行某项工作时与之互动的一系列 Activity 的集合. 一.步骤,修改build.gradle,添加cmakelists,写JNI接口,写c++,这个是不是流水线 ...

  4. android scrollview焦点,scrollview里面的edittext,当它获得焦点时如何滚动到edittext

    在scrollview中有一个edittext. (并且edittext上方的scrollview中还有其他视图.) 当用户按下edittext时,键盘变得可见,并且scrollview的可见区域变得 ...

  5. Android之解决JsonObject里面的JsonArray数据会有斜杠问题

    1.问题 本地保存了多个json格式的字符串 {"event":"sdk_ad_request_status","timestamp":16 ...

  6. Android项目实战(十六):QQ空间实现(一)—— 展示说说中的评论内容并有相应点击事件...

    大家都玩QQ空间客户端,对于每一个说说,我们都可以评论,那么,对于某一条评论: 白雪公主 回复 小矮人 : 你们好啊~ 我们来分析一下: 1.QQ空间允许我们 点击 回复人和被回复人的名字就可以进入对 ...

  7. Android stdio build.gradle buildscript 里面的repositories 和allprojects里面 repositories 的区别

    第一段 buildscript 里面的 repositories 表示只有编译工具才会用这个仓库. 比如 buildscript 里面的 dependencies classpath 'com.and ...

  8. 关于 android 里面的 AndroidX 和 annotation 冲突的解决方式

    这里我使用的是Android Studio 之前项目接入的SDK 都没有依赖AndroidX 最近接入了一个SDK 必须依赖AndroidX后就发现各种报错了 其中一个就是 程序包 android.s ...

  9. Android Studio里面的Build.gradle的详细配置说明

    Android Studio里面的Build.gradle的详细配置说明 [java] view plain copy print ? apply plugin: 'com.android.appli ...

最新文章

  1. Java控制层怎么调用适配器_java – 从适配器调用片段方法
  2. (0088)iOS开发之单例的写法以及重新认识
  3. windows 10 上office2016 word崩溃的解决方案
  4. python idle编辑的代码文件拓展名是_Python IDLE编辑器打开后缀名为.py的文件
  5. 内表数据写到服务器上
  6. File类创建删除功能的方法
  7. mysql查询正在执行的存储过程,[转]ms sql server 存储过程,查看正在执行的sql语句...
  8. lisp 设计盘形齿轮铣刀_机械设计基础——周转轮系传动比的计算
  9. c语言数组的声明和初始化_C声明和初始化能力问题和解答
  10. php生成pdf中文断码_Rmarkdown导出中文PDF解决方案
  11. hadoop中mapreduce参数优化
  12. mysql 5.6.34 二进制下载_mysql 5.6.34 二进制
  13. 【原】让两个DIV高度一样的Javascript函数
  14. Converter使用及其原理
  15. Multilingual预训练的那些套路
  16. [demo] 微信小程序Demo:树芽读书(一个不错的书籍朗读小程序)
  17. 睡眠分期--深度学习算法
  18. echars 柱状图靠左_Echarts柱状图
  19. 白盒测试的几种覆盖方法:语句覆盖、判定覆盖、条件覆盖、判定/条件覆盖、组合覆盖和路径覆盖详解
  20. excel 删除大量空白行

热门文章

  1. Skype for business企业语音配置之七 设置呼叫转接
  2. 云顶之弈机器人怎么拉人_《云顶之弈》机器人阵容怎么玩 快乐机器人攻略分享...
  3. 86400000L什么意思?
  4. selenium 隐藏窗口_查找Facebook用户的隐藏好友和社群
  5. Kotlin学习笔记四、集合set-容器list-映射map相关
  6. 二极管电路图如图所示,试分析各电路中二极管的工作状态,并求出输出电压值,设二极管的导通电压为Vd=0.7V
  7. 你评论,我赠书~【TFS-CLUB社区 第9期赠书活动】〖HTML5+CSS3+JavaScript从入门到精通(微课精编版)(第2版)〗等你来拿
  8. sqli-labs靶场15-19关通关笔记中总结
  9. lol观战服务器维护,lol官方助手如何观战,哪些服务器支持观战
  10. 三国志战略版:Daniel_202002_武将分析-鲁肃