这次我对聊天应用的表情包进行了编写,包括聊天表情图片的加载、聊天表情的发送(分为两部分,系统键盘输入时和自定义键盘输入时分情况处理)

EmojiUtils类中先定义两个个数组来存储所有的表情,一个其中存R.drawable中的图片,另一个存表情对应的所有字符串

    private static final int[] EMOJI_INDEX = {R.drawable.d_hehe, // 呵呵R.drawable.d_keai, // 可爱R.drawable.d_taikaixin, // 太开心R.drawable.d_guzhang, // 鼓掌R.drawable.d_xixi, // 嘻嘻R.drawable.d_haha, // 哈哈R.drawable.d_xiaoku, // 笑哭R.drawable.d_tiaopi, // 调皮R.drawable.d_chanzui,// 馋嘴R.drawable.d_heixian, // 黑线R.drawable.d_han, // 汗R.drawable.d_wabishi, // 挖鼻屎R.drawable.d_heng, // 哼R.drawable.d_nu, // 怒R.drawable.d_kelian, // 可怜R.drawable.d_liulei, // 流泪R.drawable.d_daku, // 大哭R.drawable.d_haixiu,// 害羞R.drawable.d_aini, // 爱你R.drawable.d_qinqin,// 亲亲R.drawable.face_delete,// 删除键R.drawable.d_doge, // dogeR.drawable.d_miao, // miaoR.drawable.d_yinxian, //阴险R.drawable.d_touxiao,// 偷笑R.drawable.d_ku, // 酷R.drawable.d_sikao, // 思考R.drawable.d_baibai, // 拜拜R.drawable.d_bishi, // 鄙视R.drawable.d_bizui, // 闭嘴R.drawable.d_chijing, // 吃惊R.drawable.d_dahaqi, // 打哈欠R.drawable.d_dalian, // 打脸R.drawable.d_ganmao, // 感冒R.drawable.d_kun, // 困R.drawable.d_zhouma, // 咒骂R.drawable.d_shengbing,// 生病R.drawable.d_shiwang, // 失望R.drawable.d_shuai, // 衰R.drawable.d_shuijiao, // 睡觉R.drawable.d_tu, // 吐R.drawable.face_delete,// 删除R.drawable.d_weiqu, // 委屈R.drawable.d_xu, // 嘘R.drawable.d_yiwen, // 疑问R.drawable.d_yun, // 晕R.drawable.d_zuohengheng, // 左哼哼R.drawable.d_youhengheng, // 右哼哼R.drawable.d_zhuakuang,// 抓狂R.drawable.d_zhutou, // 猪头R.drawable.xinsui, // 心碎R.drawable.l_xin, // 心R.drawable.h_xihuanni, // 喜欢你R.drawable.h_buyao, // 不要R.drawable.h_bang, // 棒R.drawable.h_lai,  // 来R.drawable.h_ok,  // OKR.drawable.h_quantou, // 拳头R.drawable.h_ruo, // 弱R.drawable.h_woshou, // 握手R.drawable.h_shengli, //胜利R.drawable.h_zan, // 赞R.drawable.face_delete,// 删除R.drawable.o_lazhu, // 蜡烛R.drawable.o_liwu, // 礼物R.drawable.o_dangao, // 蛋糕R.drawable.o_feiji, // 飞机R.drawable.o_ganbei, // 干杯R.drawable.o_weiguan, // 围观R.drawable.w_fuyun, // 云R.drawable.w_taiyang, // 太阳R.drawable.w_weifeng, // 微风R.drawable.w_xiayu, // 下雨R.drawable.w_yueliang, // 月亮R.drawable.face_delete // 删除};private static final String[] EMOJI_NAME = {"[呵呵]","[可爱]","[太开心]","[鼓掌]","[嘻嘻]","[哈哈]","[笑哭]","[调皮]","[馋嘴]","[黑线]","[汗]","[挖鼻屎]","[哼]","[怒]","[可怜]","[流泪]","[大哭]","[害羞]","[爱你]","[亲亲]","[删除]","[doge]","[miao]","[阴险]","[偷笑]","[酷]","[思考]","[拜拜]","[鄙视]","[闭嘴]","[吃惊]","[打哈欠]","[打脸]","[感冒]","[困]","[咒骂]","[生病]","[失望]","[衰]","[睡觉]","[吐]","[删除]","[委屈]","[嘘]","[疑问]","[晕]","[左哼哼]","[右哼哼]","[抓狂]","[猪头]","[心碎]","[心]","[喜欢你]","[不要]","[棒]","[来]","[OK]","[拳头]","[弱]","[握手]","[胜利]","[赞]","[删除]","[蜡烛]","[礼物]","[蛋糕]","[飞机]","[干杯]","[围观]","[云]","[太阳]","[微风]","[下雨]","[月亮]","[删除]",};

自定义一个EmojiBean类,为每个表情对象添加indext和name属性。

public class EmojiBean implements Serializable {private int mResIndex;private String mEmojiName;public int getResIndex() {return mResIndex;}public void setResIndex(int resIndex) {mResIndex = resIndex;}public String getEmojiName() {return mEmojiName;}public void setEmojiName(String emojiName) {mEmojiName = emojiName;}
}

在EmojiUtil中创建一个EmojiList,存储每个表情的indext和name

private static void createEmojiList(){sEmojiBeans = new ArrayList<>();sEmojiMap = new HashMap<>();EmojiBean emojiBean;for (int i = 0;i<EMOJI_INDEX.length;i++){emojiBean = new EmojiBean();emojiBean.setResIndex(EMOJI_INDEX[i]);emojiBean.setEmojiName(EMOJI_NAME[i]);sEmojiBeans.add(emojiBean);sEmojiMap.put(EMOJI_NAME[i],EMOJI_INDEX[i]);}}

通过获得BitmapFactory里面的Options类来解码Bitmap时的各种参数控制。

public static Bitmap decodeBitmapFromRes(Resources res, int resId,int reqWidth, int reqHeight) {// 第一次解析将inJustDecodeBounds设置为true,来获取图片大小final BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;BitmapFactory.decodeResource(res, resId, options);// 调用上面定义的方法计算inSampleSize值options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);// 使用获取到的inSampleSize值再次解析图片options.inJustDecodeBounds = false;return BitmapFactory.decodeResource(res, resId, options);}

把dip值转换为pix像素值的方法

    public static int dip2px(Context context, float dipValue) {final float scale = context.getResources().getDisplayMetrics().density;return (int) (dipValue * scale + 0.5f);}

计算源图片的宽和高与实际显示时的比例,如果源图片较大,则返回1,否则返回比率中较小的那个

public static int calculateInSampleSize(BitmapFactory.Options options,int reqWidth, int reqHeight) {// 源图片的高度和宽度final int height = options.outHeight;final int width = options.outWidth;int inSampleSize = 1;if (height > reqHeight || width > reqWidth) {// 计算出实际宽高和目标宽高的比率final int heightRatio = Math.round((float) height / (float) reqHeight);final int widthRatio = Math.round((float) width / (float) reqWidth);// 选择宽和高中最小的比率作为inSampleSize的值,这样可以保证最终图片的宽和高// 一定都会大于等于目标的宽和高。inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;}return inSampleSize;}

编写方法用于将字符串和表情图片进行匹配,textSize将来传入文本框的大小

public static SpannableString text2Emoji(Context context,final String source,final float textSize) {SpannableString spannableString = new SpannableString(source);Resources res = context.getResources();String regexEmotion = "\\[([\u4e00-\u9fa5\\w])+\\]";Pattern patternEmotion = Pattern.compile(regexEmotion);Matcher matcherEmotion = patternEmotion.matcher(spannableString);while (matcherEmotion.find()) {// 获取匹配到的具体字符String key = matcherEmotion.group();// 匹配字符串的开始位置int start = matcherEmotion.start();// 利用表情名字获取到对应的图片Integer imgRes = getImgByName(key);if (imgRes != 0) {// 压缩表情图片int size = (int) (textSize * 13.0f / 10.0f);Bitmap bitmap = BitmapFactory.decodeResource(res, imgRes);Bitmap scaleBitmap = Bitmap.createScaledBitmap(bitmap, size, size, true);ImageSpan span = new ImageSpan(context, scaleBitmap);spannableString.setSpan(span, start, start + key.length(),Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);}}return spannableString;}

点击表情的监听器的接口,在未来的布局类中会实现这个接口内的方法。

public interface OnExpressSelListener{void onEmojiSelect(EmojiBean emojiBean);void onEmojiDelete();}

表情包的布局类,接口内选择和删除的方法在另一个类中实现

    private void init(){mExpressViews = new ArrayList<>();mEmojiLayout = new EmojiLayout(getContext());mEmojiLayout.setSelectListener(new EmojiLayout.OnEmojiSelectListener() {@Overridepublic void emojiSelect(EmojiBean emojiBean) {if (mOnExpressSelListener != null){mOnExpressSelListener.onEmojiSelect(emojiBean);}}@Overridepublic void emojiDelete() {if (mOnExpressSelListener != null){mOnExpressSelListener.onEmojiDelete();}}});

创新实训——第三周2相关推荐

  1. (个人)AR电子书系统创新实训第三周(2)

    上一篇我介绍了相关控件的搭建以及sprite的处理,在这一篇我将介绍各个控件的组织以及相关的实现代码. 1."设置"弹窗及按钮实现 在上篇博文中我已经介绍了如何建立"弹窗 ...

  2. (个人)太极拳学习系统创新实训第三周(一)

    本周任务: 这周的主要任务是实现基于Unreal Engine 4的VR交互,我将介绍我在这周完成的VR交互的进度和在实现过程中遇到的具体问题. 主要过程: 首先在Unreal Engine 4中创建 ...

  3. 项目实训第三周第三次

    项目实训第三周第三次记录 1.任务安排 2.任务分析 2.1显示待审核的申诉请求 2.2同意申诉请求 2.3拒绝申诉请求 3.具体代码 3.1AppealMapper 3.2AppealService ...

  4. 山东大学软件学院项目实训-创新实训-SDUMeeting(三)

    山东大学软件学院项目实训-创新实训-SDUMeeting(三) 山大会议项目web安全之文件注入防护 一.前言 山大会议的客户端加入了对用户自定义头像的支持,需要用户自行上传头像图片,这个过程存在文件 ...

  5. 山东大学软件学院项目实训第三周

    我们小组实现考试管理,实现了学生端,老师端,管理员端的界面展示,对试卷的删除操作等. 以下是我们组后端部分的代码 package com.mwt.oes.controller;import com.m ...

  6. (个人)AR电子书系统创新实训第五周(2)

    设计桌面端应用的工作流程&实现资源导入,管理系统 根据需要,我再次整理了一下桌面端程序的功能,该程序具有配对(映射)资源.打包资源.上传资源.以及生成二维码的功能,具体流程图如下: 据此,我首 ...

  7. (个人)VR实时交互的太极拳学习系统创新实训第七周(2)

    标准动画信息的重动捕 因为开始使用了demo中,使用的是一个简单的机器人,不符合最终成品的要求,因此和组里另一名成员进行新的模型动作的制作-----使用一个穿着太极拳服的角色重新进行动捕. 为了使原来 ...

  8. 创新实训-python爬虫多线程|解决中文乱码问题|卡片向上浮动效果|图文切换

    创新实训-python爬虫多线程|乱码问题|前端样式重新修改 考完毛概,把上周的工作总结一下.爬虫在第一周的时候只爬了一个就业指导这一个模块,这一次又加了招聘服务模块,所以就用了两个线程.前端首页一开 ...

  9. 创新实训(2)-Scrapy 学习

    创新实训(2)-Scrapy 学习 参考资料:Scrapy 0.25 文档 1.Scrapy简介 Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 可以应用在包括数据挖掘,信息处理 ...

最新文章

  1. idea不区分大小写设置_我的 IntelliJ IDEA 一直都是这么设置的,效果很棒!
  2. [Codeforces Round #194 (Div. 2)] Secret 解题报告 (数学)
  3. Java 7中的Try-with-resources
  4. 数字化转型的路上,手握一张地图,但路还得自己走
  5. CodeForces - 1301C Ayoub's function(数学)
  6. 给具有SAP传统产品ABAP开发经验的朋友介绍SAP C4C
  7. 面试了 N 个候选人后,我总结出这份 Java 面试准备技巧
  8. 在linux下解压jdk时出现的问题
  9. Sobel两种算子形式
  10. Tarjan-有向图
  11. 电大计算机考试将网页保存到桌面,电大计算机网考小抄.pdf
  12. win10 多开 vpn
  13. linux音频alsa-uda134x驱动分析之一(over-view)
  14. lvgl 主要文件目录树
  15. abaqus的python安装文件在哪_Abaqus2016安装教程【附软件下载地址】
  16. dx逆向建模步骤_初级反求逆向建模(一)
  17. PHP在线网课问答题库搜索,推荐一个大学mooc网课答案题库在线查询公众号
  18. bzoj5294: [Bjoi2018]二进制(线段树)
  19. 七夕将至,20行js代码给女友做个卡通P图微信机器人
  20. MTK交换机PHY 方案Airoha达发(econet)概要

热门文章

  1. 对索伯列夫空间的一个浅显易懂的解释
  2. 09 MySQL 从入门到精通——数据查询
  3. Java安全通信:HTTPS与SSL
  4. JAVA有没有moba游戏_盘点那些年5V5的MOBA游戏,除了王者荣耀,还有其他的精品!...
  5. 截取android正在播放音乐的audio音频流(后台获取android音频流)
  6. 数学建模 # 论文撰写技巧
  7. svn: E155007: 'F:\XXX' is not a working copy directory 解决方法
  8. 硬件和软件对虚拟化的支持
  9. 计算机专业报考广东哪所学校,广东哪些大学有人工智能专业
  10. Stm32开发1-蓝牙实现STM32的无线烧写程序 ISP模式 串口1不受影响 无线下载