偶然在一个需求中需要解析qq聊天记录表情,表情的格式是以/开始,比如:你好啊?/微笑,在网上找了半天,也没能找到一个比较合适的,所以准备自己实现一下,首先要将表情图片和表情字符对上号,我想了几种解决方案:
最后用了这种,操了qq的安装包,会发现,表情分为三种,一种是f_static_093.png,还有emoji_058.png,还有f022.gif,gif不知道怎么能显示好,emoji表情用的人不多,至少我很少用。所以就从f_static_106.png入手,一共107个表情都是以f_static_开始+数字.png ,然后用最笨的方法,找到表情对应的字符串,生成了一个faces.xml
<?xml version="1.0" encoding="utf-8"?> <resources> <string-array name="qqFaces"> <item>呲牙</item> <item>调皮</item> <item>冷汗</item> <item>偷笑</item> <item>再见</item> <item>敲打</item> <item>擦汗</item> <item>猪头</item> <item>玫瑰</item> <item>流泪</item> <item>大哭</item> <item>嘘...</item> <item>酷</item> <item>抓狂</item> <item>委屈</item> <item>便便</item> <item>炸弹</item> <item>菜刀</item> <item>可爱</item> <item>色</item> <item>害羞</item> <item>得意</item> <item>吐</item> <item>微笑</item> <item>发怒</item> <item>尴尬</item> <item>惊恐</item> <item>冷汗</item>
........
下面的工作就是解析出聊天记录中的表情,然后用图片替换字符串,找了几个大神的类似的demo里面都是用正则法则,但是我想换一个思路,所以就用了分割字符串的方法,将字符串从/处分割为一个数组,然后将前2,1,3个字符和表情的hashmap中比对,如果找到了表情,那么就将这表情用图片代替,其间没有什么难处,就是逻辑上有点饶,没有正则法则实现起来清爽,有一个注意点就是,根据拼接的图片名称找图片ID,代码如下,关键地方的注释已经加好:
public class FaceUtil { HashMap<String, Integer> mFaceHash; private Context context; public FaceUtil(Context context) { this.context = context; mFaceHash = new HashMap<String, Integer>(); String faceStr[] = context.getResources().getStringArray( R.array.qqFaces); for (int i = 0; i < faceStr.length; i++) { mFaceHash.put(faceStr[i], i); } } /** * 得到一个SpanableString对象,通过传入的字符串,并进行正则判断 * * @param context * @param str * @return */ public SpannableString getExpressionString(String str) { SpannableString spannableString = new SpannableString(str); String record[] = str.split("/"); String msgStr = record[0]; // 计算长度的拼接字符串 if (record.length > 1) for (int i = 1; i < record.length; i++) { String content = record[i].trim(); int imgIndex = -1; int partLength = -1; // 计算每次表情的长度是1.2.3 if (!content.equals("")) { try { imgIndex = mFaceHash.get(content.subSequence(0, 2)); } catch (Exception e) { } if (imgIndex < 0) { try { imgIndex = mFaceHash.get(content.subSequence(0, 1)); } catch (Exception e) { } if (imgIndex < 0) { try { imgIndex = mFaceHash.get(content.subSequence(0, 3)); } catch (Exception e) { } } else { partLength = 2;// 1/ } } else { partLength = 3;// 2个/ } } if (imgIndex >= 0) { try { int resID = context.getResources().getIdentifier( "f_static_" + imgIndex, "drawable", "com.james.qqchatrecord"); Bitmap bitmap = BitmapFactory.decodeResource( context.getResources(), resID); bitmap = Bitmap .createScaledBitmap(bitmap, 50, 50, true); // 通过图片资源id来得到bitmap,用一个ImageSpan来包装 @SuppressWarnings("deprecation") ImageSpan imageSpan = new ImageSpan(bitmap); if (partLength == -1) { partLength = 4;// 如果imgIndex不是-1,那就是有图片的,如果paetLength=-1,那么就能确认是3个长度的字符串 } spannableString.setSpan(imageSpan, msgStr.length(), msgStr.length() + partLength, Spannable.SPAN_INCLUSIVE_EXCLUSIVE); } catch (Exception e) { e.printStackTrace(); } } msgStr = msgStr + record[i] + "/";// spannableString的长度不会变,也就是说不是在字符串的基础上修改,而是有备份,那样的话就要把/长度算上 } return spannableString; } }
用的地方之间
peopleBcontent.setText(
mFaceUtil
.getExpressionString(itemData
.getContent().trim()));就ok,
效果如下