package com.wisedu.scc.love.widget.emoji; import android.content.Context; import android.text.Spannable; import android.text.SpannableString; import android.text.TextUtils; import android.util.Log; import com.wisedu.scc.love.R; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; public class EmojiConversionUtil { /** 每一页表情的个数 */ private static final int PAGE_SIZE = 24; private static final int TEXT_EMOJI_PAGE_SIZE = 9; private static EmojiConversionUtil mFaceConversionUtil; /** 保存于内存中的表情HashMap */ private HashMap<String, String> emojiMap = new HashMap<String, String>(); /** 保存于内存中的表情集合 */ private List<Emoji> emojis = new ArrayList<Emoji>(); /** 表情分页的结果集合 */ public List<List<Emoji>> emojiLists = new ArrayList<List<Emoji>>(); private List<String> textEmojis = new ArrayList<String>(); public List<List<String>> textEmojiLists = new ArrayList<List<String>>(); private Context mContext; private EmojiConversionUtil(Context context) { getFileText(context); mContext = context; initTextEmojis(context); } private void initTextEmojis(Context context) { Collections.addAll(textEmojis, context.getResources().getStringArray(R.array.text_emojis)); int pageCount = (int) Math.ceil(textEmojis.size() / TEXT_EMOJI_PAGE_SIZE + 0.1); for (int i = 0; i < pageCount; i++) { textEmojiLists.add(getTextEmojiData(i)); } } public static EmojiConversionUtil getInstace(Context context) { if (mFaceConversionUtil == null) { mFaceConversionUtil = new EmojiConversionUtil(context); } return mFaceConversionUtil; } /** * 得到一个SpanableString对象,通过传入的字符串,并进行正则判断 * @param str * @return */ public SpannableString getExpressionString(CharSequence str) { return getExpressionString(str, 29); } public SpannableString getExpressionString(CharSequence str, int size) { SpannableString spannableString = new SpannableString(str); // 正则表达式比配字符串里是否含有表情,如: 我好[开心]啊 String zhengze = "\\[[^\\]]+\\]"; // 通过传入的正则表达式来生成一个pattern Pattern sinaPatten = Pattern.compile(zhengze, Pattern.CASE_INSENSITIVE); try { size += 10;// 用EditText的size会使得表情添加上去略小,这边hack一下 dealExpression(spannableString, sinaPatten, 0, size); } catch (Exception e) { Log.e("dealExpression", e.getMessage()); } return spannableString; } /** * 添加表情 * * @param context * @param imgId * @param spannableString * @return */ public SpannableString addFace(Context context, int imgId, String spannableString, int size) { if (TextUtils.isEmpty(spannableString)) { return null; } size += 10;// 用EditText的size会使得表情添加上去略小,这边hack一下 EmojiconSpan emojiconSpan = new EmojiconSpan(context, imgId, size); SpannableString spannable = new SpannableString(spannableString); spannable.setSpan(emojiconSpan, 0, spannableString.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); return spannable; } /** * 对spanableString进行正则判断,如果符合要求,则以表情图片代替 * * @param spannableString * @param patten * @param start * @throws Exception */ private void dealExpression(SpannableString spannableString, Pattern patten, int start, int size) throws Exception { Matcher matcher = patten.matcher(spannableString); while (matcher.find()) { String key = matcher.group(); // 返回第一个字符的索引的文本匹配整个正则表达式,ture 则继续递归 if (matcher.start() < start) { continue; } String value = emojiMap.get(key); if (TextUtils.isEmpty(value)) { continue; } // 通过上面匹配得到的字符串来生成图片资源id int resId = mContext.getResources().getIdentifier(value, "drawable", mContext.getPackageName()); if (resId != 0) { EmojiconSpan emojiconSpan = new EmojiconSpan(mContext, resId, size); // int end = matcher.start() + key.length(); // 将该图片替换字符串中规定的位置中 spannableString.setSpan(emojiconSpan, matcher.start(), matcher.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); // if (end < spannableString.length()) { // // 如果整个字符串还未验证完,则继续。。 // //dealExpression(context, spannableString, patten, end); // } // break; } } } public EmojiconSpan dealExpression(String emoji, int size) { String value = emojiMap.get(emoji); if (TextUtils.isEmpty(value)) { return null; } int resId = mContext.getResources().getIdentifier(value, "drawable", mContext.getPackageName()); EmojiconSpan emojiconSpan = null; if (resId != 0) { emojiconSpan = new EmojiconSpan(mContext, resId, size, EmojiconSpan.ALIGN_BASELINE); } return emojiconSpan; } public void getFileText(Context context) { parseData(FileUtils.getEmojiFile(context), context); } /** * 解析字符 * * @param data */ private void parseData(List<String> data, Context context) { if (data == null) { return; } Emoji emojEentry; try { for (String str : data) { String[] text = str.split(","); String fileName = text[0] .substring(0, text[0].lastIndexOf(".")); emojiMap.put(text[1], fileName); int resID = context.getResources().getIdentifier(fileName, "drawable", context.getPackageName()); if (resID != 0) { emojEentry = new Emoji(); emojEentry.setId(resID); emojEentry.setCharacter(text[1]); emojEentry.setFaceName(fileName); emojis.add(emojEentry); } } int pageCount = (int) Math.ceil(emojis.size() / PAGE_SIZE + 0.1); for (int i = 0; i < pageCount; i++) { emojiLists.add(getData(i)); } } catch (Exception e) { e.printStackTrace(); } } /** * 获取分页数据 * * @param page * @return */ private List<Emoji> getData(int page) { int startIndex = page * PAGE_SIZE; int endIndex = startIndex + PAGE_SIZE; if (endIndex > emojis.size()) { endIndex = emojis.size(); } // 不这么写,会在viewpager加载中报集合操作异常,我也不知道为什么 List<Emoji> list = new ArrayList<Emoji>(); list.addAll(emojis.subList(startIndex, endIndex)); if (list.size() < PAGE_SIZE) { for (int i = list.size(); i < PAGE_SIZE; i++) { Emoji object = new Emoji(); list.add(object); } } return list; } private List<String> getTextEmojiData(int page){ int startIndex = page * TEXT_EMOJI_PAGE_SIZE; int endIndex = startIndex + TEXT_EMOJI_PAGE_SIZE; if (endIndex > textEmojis.size()) { endIndex = textEmojis.size(); } List<String> list = new ArrayList<String>(); list.addAll(textEmojis.subList(startIndex, endIndex)); if (list.size() < TEXT_EMOJI_PAGE_SIZE) { for (int i = list.size(); i < TEXT_EMOJI_PAGE_SIZE; i++) { list.add(new String()); } } return list; } }