应用需要用到聊天功能,考虑到开始需求不大,暂时先用第三方的。

一研究发现界面风格有点不符合整体的风格,加上需要一些自己的特定的需求和界面显示,于是就决定调用第三方数据接口,界面自己写。功能只需要文字,表情和语音就ok,我选择先做表情的。

表情一般都是用 [] 或者类似这种 "/:^_^", "/:^$^", "/:Q" 方式表示,我们用到的就是后者。解析消息类似于:  /:^_^你好,abc。

基本思路就是:找到每个/:开头的,然后截取后面的N位,放到表情数组去匹配,然后继续下一个,直到末尾。接着统计了表情数组,记录了总共有哪些长度的表情字符,还按统计的数目对长度排了个序,出现次数多的长度排在前面。

public CharSequence initMessageRecord(String content){
SpannableStringBuilder ssb = new SpannableStringBuilder(content);
int[] smileLen = IMSmilyCache.getLenIndex();
int contentLen = content.length();
int index = 0;
String tempContent = content;
while (index < contentLen) {
content = tempContent.substring(index);
int nextIndex = content.indexOf("/:", 1); String tmpStr;
if (nextIndex >= 0) {
tmpStr = content.substring(0, nextIndex);
} else {
tmpStr = content;
}
int resId = IMSmilyCache.getInstance().getSimpleShortCutDrawable(tmpStr);
if (resId != -1) {
initFace(ssb, resId, index,index + tmpStr.length());
} else {
//截取的字符串没直接匹配到表情
String tmpTarget;
for (int tmpLen : smileLen) {
if (tmpStr.length() < tmpLen)
continue;
tmpTarget = tmpStr.substring(0, tmpLen);
resId = IMSmilyCache.getInstance().getSimpleShortCutDrawable(tmpTarget);
if (resId != -1) {
initFace(ssb, resId, index, index + tmpTarget.length()); tmpStr = tmpTarget;
break;
}
}
}
index += tmpStr.length();
}
return ssb;
} private void initFace(SpannableStringBuilder ssb, int resId, int start, int end) {
Drawable d = activity.getResources().getDrawable(resId);
d.setBounds(0, 0, d.getIntrinsicWidth(), d.getIntrinsicHeight());
ImageSpan span = new ImageSpan(d, ImageSpan.ALIGN_BASELINE);
ssb.setSpan(span, start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}

解析表情函数

 public class IMSmilyCache {
private static String[] meanings = {"微笑", "害羞", "吐舌头", "偷笑", "爱幕", "大笑", "跳舞", "飞吻", "安慰", "抱抱", "加油", "胜利", "强", "亲亲", "花痴", "露齿笑", "查找", "呼叫", "算账", "财迷", "好主意", "鬼脸", "天使", "再见", "流口水", "享受", "色情狂", "呆若木鸡", "思考", "迷惑", "疑问", "没钱了", "无聊", "怀疑", "嘘", "小样", "摇头", "感冒", "尴尬", "傻笑", "不会吧", "无奈", "流汗", "凄凉", "困了", "晕", "忧伤", "委屈", "悲泣", "大哭", "痛哭", "I服了U", "对不起", "再见", "皱眉", "好累", "生病", "吐", "背", "惊讶", "惊愕", "闭嘴", "欠扁", "鄙视你", "大怒", "生气", "财神", "学习雷锋", "恭喜发财", "小二", "老大", "邪恶", "单挑", "CS", "隐形人", "炸弹", "惊声尖叫", "漂亮MM", "帅哥", "招财猫", "成交", "鼓掌", "握手", "红唇", "玫瑰", "残花", "爱心", "心碎", "钱", "财物", "礼物", "收邮件", "电话", "举杯庆祝", "时钟", "等待", "很晚了", "飞机", "支付宝"};
private static IMSmilyCache mSmilyCache = new IMSmilyCache();
private static int[] lenIndex; /**
* 此处优化表情查找速度,按出现次数的概率从大到小排序
*/
static {
HashMap<Integer, Integer> map = new HashMap<>();
int[] len = new int[20];
for (int i = 0; i < shortCuts.length; i++) {
int cutsLen = shortCuts[i].length();
len[cutsLen]++;
} for (int i = 0; i < len.length; i++) {
if (len[i] != 0) {
map.put(len[i], i);
}
} SortUtil sortUtil = new SortUtil();
sortUtil.sort(len); int size = 0;
for (int i = 0; i < len.length; i++) {
if (len[i] == 0) {
size = i;
break;
}
}
lenIndex = new int[size];
for (int i = 0; i < size; i++) {
lenIndex[i] = map.get(len[i]);
} LogUtils.fff(""+ Arrays.toString(lenIndex));
} public static void main(String[] args) {
System.out.println(shortCuts.length);
System.out.println(meanings.length);
} public static IMSmilyCache getInstance() {
return mSmilyCache;
} public String[] getShortCuts() {
return shortCuts;
} public int getSimpleShortCutDrawable(String context){
for (int i = 0; i < shortCuts.length; i++) {
if (context.equals(shortCuts[i])) {
return smileResArray[i];
}
}
if (context.equals("shanchu")) {
return R.drawable.aliwx_shanchu_dw;
}
return -1;
} public static int[] getLenIndex() {
return lenIndex;
}
}

表情工具类

===============

关于删除表情的操作,在使用过程用发现,使用系统自带的键盘能够正确的删除整个表情,于是删除按钮事件就只有两行代码

KeyEvent keyEventDown = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_DEL);
editText.onKeyDown(KeyEvent.KEYCODE_DEL, keyEventDown);

Android 解析聊天表情的笔记的更多相关文章

  1. Android 聊天表情输入、表情翻页带效果、下拉刷新聊天记录

    经过一个星期的折腾,最终做完了这个Android 聊天表情输入.表情翻页带效果.下拉刷新聊天记录.这仅仅是一个单独聊天表情的输入,以及聊天的效果实现.由于我没有写server,所以没有两方聊天的效果. ...

  2. Android(java)学习笔记205:网易新闻RSS客户端应用编写逻辑过程

    1.我们的项目需求是编写一个新闻RSS浏览器,RSS(Really Simple Syndication)是一种描述和同步网站内容的格式,是使用最广泛的XML应用.RSS目前广泛用于网上新闻频道,bl ...

  3. Android(java)学习笔记219:开发一个多界面的应用程序之两种意图

    1.两种意图: (1)显式意图: 在代码里面用intent设置要开启Activity的字节码.class文件: (2)隐式意图: Android(java)学习笔记218:开发一个多界面的应用程序之人 ...

  4. Android(java)学习笔记148:网易新闻RSS客户端应用编写逻辑过程

    1.我们的项目需求是编写一个新闻RSS浏览器,RSS(Really Simple Syndication)是一种描述和同步网站内容的格式,是使用最广泛的XML应用.RSS目前广泛用于网上新闻频道,bl ...

  5. Android(java)学习笔记162:开发一个多界面的应用程序之两种意图

    1.两种意图: (1)显式意图: 在代码里面用intent设置要开启Activity的字节码.class文件: (2)隐式意图: Android(java)学习笔记218:开发一个多界面的应用程序之人 ...

  6. Android自动化测试之Monkeyrunner学习笔记(一)

    Android自动化测试之Monkeyrunner学习笔记(一) 因项目需要,开始研究Android自动化测试方法,对其中的一些工具.方法和框架做了一些简单的整理,其中包括Monkey.Monkeyr ...

  7. android解析XML总结(SAX、Pull、Dom三种方式) <转载>

    android解析XML总结(SAX.Pull.Dom三种方式) http://www.cnblogs.com/JerryWang1991/archive/2012/02/24/2365507.htm ...

  8. Android(java)学习笔记267:Android线程池形态

    1. 线程池简介  多线程技术主要解决处理器单元内多个线程执行的问题,它可以显著减少处理器单元的闲置时间,增加处理器单元的吞吐能力.     假设一个服务器完成一项任务所需时间为:T1 创建线程时间, ...

  9. Android 实现emoji表情的demo

    Android 实现emoji表情的例子,网上看到的,记录一下. 请看下图 : 项目下载地址:http://download.csdn.net/detail/abc13939746593/741397 ...

随机推荐

  1. android ImageView网络图片加载、动态设置尺寸、圆角..

    封装了一个关于ImageView的辅助类,该类可以方便实现网络图片下载的同时,动态设置图片尺寸.圆角.....一系列连贯的操作,无样式表,java代码实现所有功能,使用很方便. package com ...

  2. Map集合

    1:Map (1)将键映射到值的对象. 一个映射不能包含重复的键:每个键最多只能映射到一个值. 键值对的方式存在 (2)Map和Collection的区别? A:Map 存储的是键值对形式的元素,键唯 ...

  3. 用C++实现的贪吃蛇游戏

    我是一个C++初学者,控制台实现了一个贪吃蛇游戏. 代码如下: //"贪吃蛇游戏"V1.0 //李国良于2016年12月29日编写完成 #include <iostream& ...

  4. Java-加载数据库驱动,取得数据库连接

    在Java中想要进行数据库操作,最重要的两个步骤就是加载数据驱动,然后取得数据库连接. 1.加载 数据库驱动( Class.forName(String className) ): 因为Java是一种 ...

  5. Windows安装RabbitMQ集群的几个注意点

    记录一下RabbitMQ在windows平台下安装的几个注意点- -,好记性不如烂笔头 安装过程与Linux安装一致,教程参照官网集群配置:此处只列举出几个注意点: 1. erlang的版本需要一致, ...

  6. struts2杂记(一)——使用doubleSelect

    一.前言 这段时间忙的要死,做项目,学框架,时间根本不够用,只能尽量抽出时间记录自己学过的东西. 1.1.doubleSelect 在之前学习中,我们使用过二级列表,相信很多人都理解其原理,在stru ...

  7. react-echarts之折线图的显示

    react中想要实现折线图和饼图的功能,需要引入react-echarts包,然后再实现折线图的功能.我这里引用的版本是:0.1.1.其他的写法参echarts官网即可.下面详细讲解的是我在react ...

  8. switch语句的妙用

    switch语句的普通用法很简单,如下: var a = 3; switch (a) { case 1: console.log(a); break; case 2: case 3: console. ...

  9. 整理分享原生态mac AndroidStudio的快捷键

    使用AndroidStudio开发半年了,一路爬坑至今,刚由Windows转mac一个星期.通过查些资料和自己摸索,记录一些常用的快捷键,犹豫个人不喜欢改快捷键,所以都是原生的.特此分享给大家!欢迎补 ...

  10. Linux 6.5(oracle 11.2.0.4)单实例ASM安装

    Linux 6.5(oracle 11.2.0.4) 1.解析主机.配置网络等 /etc/hosts /etc/sysconfig/network /etc/init.d/NetworkManager ...