欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android编程实现QQ表情的发送和接收完整实例(附源码)

程序员文章站 2023-12-05 15:58:34
本文实例讲述了android编程实现qq表情的发送和接收。分享给大家供大家参考,具体如下: 在自己做一个聊天应用练习的时候,需要用到表情,于是就想着模仿一下qq表情,图片...

本文实例讲述了android编程实现qq表情的发送和接收。分享给大家供大家参考,具体如下:

在自己做一个聊天应用练习的时候,需要用到表情,于是就想着模仿一下qq表情,图片资源完全copy的qq.apk,解压就可以得到,这里不细说。

下面将该应用中的表情模块功能抽离出来,以便自己以后复习回顾。。

先看一下效果图:

首先进入界面:(完全仿照qq)

Android编程实现QQ表情的发送和接收完整实例(附源码)

点击一下上面的表情图标:

Android编程实现QQ表情的发送和接收完整实例(附源码)

选择一些表情,输入一些文字混合:

Android编程实现QQ表情的发送和接收完整实例(附源码)

点击发送:

Android编程实现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程序设计有所帮助。