Android编程实现QQ表情的发送和接收完整实例(附源码)
程序员文章站
2023-12-15 10:03:10
本文实例讲述了android编程实现qq表情的发送和接收。分享给大家供大家参考,具体如下:
在自己做一个聊天应用练习的时候,需要用到表情,于是就想着模仿一下qq表情,图片...
本文实例讲述了android编程实现qq表情的发送和接收。分享给大家供大家参考,具体如下:
在自己做一个聊天应用练习的时候,需要用到表情,于是就想着模仿一下qq表情,图片资源完全copy的qq.apk,解压就可以得到,这里不细说。
下面将该应用中的表情模块功能抽离出来,以便自己以后复习回顾。。
先看一下效果图:
首先进入界面:(完全仿照qq)
点击一下上面的表情图标:
选择一些表情,输入一些文字混合:
点击发送:
可以看到文字和表情图片都一起显示出来了。
下面列出一些关键代码:
表情工具类expressionutil:
public class expressionutil { /** * 对spanablestring进行正则判断,如果符合要求,则以表情图片代替 * @param context * @param spannablestring * @param patten * @param start * @throws securityexception * @throws nosuchfieldexception * @throws numberformatexception * @throws illegalargumentexception * @throws illegalaccessexception */ public static void dealexpression(context context,spannablestring spannablestring, pattern patten, int start) throws securityexception, nosuchfieldexception, numberformatexception, illegalargumentexception, illegalaccessexception { matcher matcher = patten.matcher(spannablestring); while (matcher.find()) { string key = matcher.group(); if (matcher.start() < start) { continue; } field field = r.drawable.class.getdeclaredfield(key); int resid = integer.parseint(field.get(null).tostring()); //通过上面匹配得到的字符串来生成图片资源id if (resid != 0) { bitmap bitmap = bitmapfactory.decoderesource(context.getresources(), resid); imagespan imagespan = new imagespan(bitmap); //通过图片资源id来得到bitmap,用一个imagespan来包装 int end = matcher.start() + key.length(); //计算该图片名字的长度,也就是要替换的字符串的长度 spannablestring.setspan(imagespan, matcher.start(), end, spannable.span_inclusive_exclusive); //将该图片替换字符串中规定的位置中 if (end < spannablestring.length()) { //如果整个字符串还未验证完,则继续。。 dealexpression(context,spannablestring, patten, end); } break; } } } /** * 得到一个spanablestring对象,通过传入的字符串,并进行正则判断 * @param context * @param str * @return */ public static spannablestring getexpressionstring(context context,string str,string zhengze){ spannablestring spannablestring = new spannablestring(str); pattern sinapatten = pattern.compile(zhengze, pattern.case_insensitive); //通过传入的正则表达式来生成一个pattern try { dealexpression(context,spannablestring, sinapatten, 0); } catch (exception e) { log.e("dealexpression", e.getmessage()); } return spannablestring; } }
在显示聊天页面的list的适配器中,我们需要做如下的显示,即调用上面工具类的方法:
simplechatadapter中的内部类viewholder:
private class viewholder{ relativelayout chat_layout; imageview image; textview text; public viewholder(view convertview){ chat_layout=(relativelayout) convertview.findviewbyid(r.id.team_singlechat_id_listiteam); image=(imageview) convertview.findviewbyid(r.id.team_singlechat_id_listiteam_headicon); text=(textview) convertview.findviewbyid(r.id.team_singlechat_id_listiteam_message); } public void setdata(messageinfo msg){ relativelayout.layoutparams rl_chat_left=((relativelayout.layoutparams)chat_layout.getlayoutparams()); relativelayout.layoutparams rl_tv_msg_left=((relativelayout.layoutparams)text.getlayoutparams()); relativelayout.layoutparams rl_iv_headicon_left=((relativelayout.layoutparams)image.getlayoutparams()); if(!dicqconstant.defaultmac.equalsignorecase(msg.getusermac())){ //根据本地的mac地址来判断该条信息是属于本人所说还是对方所说 //如果是自己说的,则显示在右边;如果是对方所说,则显示在左边 rl_chat_left.addrule(relativelayout.align_parent_left,-1); rl_chat_left.addrule(relativelayout.align_parent_right,0); rl_iv_headicon_left.addrule(relativelayout.align_parent_left,-1); rl_iv_headicon_left.addrule(relativelayout.align_parent_right,0); rl_tv_msg_left.addrule(relativelayout.right_of,r.id.team_singlechat_id_listiteam_headicon); rl_tv_msg_left.addrule(relativelayout.left_of,0); text.setbackgroundresource(r.drawable.balloon_l_selector); }else{ rl_chat_left.addrule(relativelayout.align_parent_left,0); rl_chat_left.addrule(relativelayout.align_parent_right,-1); rl_iv_headicon_left.addrule(relativelayout.align_parent_left,0); rl_iv_headicon_left.addrule(relativelayout.align_parent_right,-1); rl_tv_msg_left.addrule(relativelayout.right_of,0); rl_tv_msg_left.addrule(relativelayout.left_of,r.id.team_singlechat_id_listiteam_headicon); text.setbackgroundresource(r.drawable.balloon_r_selector); } image.setimageresource(prortaitutils.conversionidtores(msg.getprotrait())); //设置头像 string str = msg.getmsg(); //消息具体内容 string zhengze = "f0[0-9]{2}|f10[0-7]"; //正则表达式,用来判断消息内是否有表情 try { spannablestring spannablestring = expressionutil.getexpressionstring(context, str, zhengze); text.settext(spannablestring); } catch (numberformatexception e) { e.printstacktrace(); } catch (securityexception e) { e.printstacktrace(); } catch (illegalargumentexception e) { e.printstacktrace(); } } }
关于表情弹出框的实现如下:
mainactivity:
/** * 创建一个表情选择对话框 */ private void createexpressiondialog() { builder = new dialog(mainactivity.this); gridview gridview = creategridview(); builder.setcontentview(gridview); builder.settitle("默认表情"); builder.show(); gridview.setonitemclicklistener(new onitemclicklistener() { @override public void onitemclick(adapterview<?> arg0, view arg1, int arg2, long arg3) { bitmap bitmap = null; bitmap = bitmapfactory.decoderesource(getresources(), imageids[arg2 % imageids.length]); imagespan imagespan = new imagespan(mainactivity.this, bitmap); string str = null; if(arg2<10){ str = "f00"+arg2; }else if(arg2<100){ str = "f0"+arg2; }else{ str = "f"+arg2; } spannablestring spannablestring = new spannablestring(str); spannablestring.setspan(imagespan, 0, 4, spannable.span_exclusive_exclusive); edit.append(spannablestring); builder.dismiss(); } }); } /** * 生成一个表情对话框中的gridview * @return */ private gridview creategridview() { final gridview view = new gridview(this); list<map<string,object>> listitems = new arraylist<map<string,object>>(); //生成107个表情的id,封装 for(int i = 0; i < 107; i++){ try { if(i<10){ field field = r.drawable.class.getdeclaredfield("f00" + i); int resourceid = integer.parseint(field.get(null).tostring()); imageids[i] = resourceid; }else if(i<100){ field field = r.drawable.class.getdeclaredfield("f0" + i); int resourceid = integer.parseint(field.get(null).tostring()); imageids[i] = resourceid; }else{ field field = r.drawable.class.getdeclaredfield("f" + i); int resourceid = integer.parseint(field.get(null).tostring()); imageids[i] = resourceid; } } catch (numberformatexception e) { e.printstacktrace(); } catch (securityexception e) { e.printstacktrace(); } catch (illegalargumentexception e) { e.printstacktrace(); } catch (nosuchfieldexception e) { e.printstacktrace(); } catch (illegalaccessexception e) { e.printstacktrace(); } map<string,object> listitem = new hashmap<string,object>(); listitem.put("image", imageids[i]); listitems.add(listitem); } simpleadapter simpleadapter = new simpleadapter(this, listitems, r.layout.team_layout_single_expression_cell, new string[]{"image"}, new int[]{r.id.image}); view.setadapter(simpleadapter); view.setnumcolumns(6); view.setbackgroundcolor(color.rgb(214, 211, 214)); view.sethorizontalspacing(1); view.setverticalspacing(1); view.setlayoutparams(new layoutparams(layoutparams.fill_parent,layoutparams.wrap_content)); view.setgravity(gravity.center); return view; }
完整实例代码代码点击此处本站下载。
希望本文所述对大家android程序设计有所帮助。