Andoird支持emoji表情(完结)



上次写的是这一篇:
Andoird想支持emoji表情的曲折经历(未完待续)

http://blog.csdn.net/zhanlanmg/article/details/41241469

这一次来说说第二种方案。

首先来分析一下:
1. 我们要做的是让客户端支持emoji表情,而且有多个不同的客户端,比如android,ios,还有网页。
2. 那么从服务端来解决我觉得不是一个很好的方案,虽然可以对不同客户端分别处理,但是要明白一点,不管服务器的存储方式,客户端还是需要显示的。
3. 第二种方案是,用图片代替这个表情字符,这样子会比较好看,用户体验好一些。所以客户端是必然需要做处理的,而转换成一些标记也只是需要一个转换函数和一个逆转函数。而且我认为客户端分治方法要比服务器全盘处理好一些。
所以这一种方案的结果是,所有内容都放在客户端处理。服务器不做任何调整,这样修改的东西少一些。主要是服务器修改起来会更加费事。

解决方案:
由于有githug上发现有人已经实现了,所以我也就拿来主义了,不过把源码看了一遍,写得很好,肯定比我写的好,不过实现的想法是一样的。
githug Emojicon : https://github.com/rockerhieu/emojicon
也可以在这里下载:http://pan.baidu.com/s/1sjlsRGL

里面有个demo可以直接使用。

简单来说原理:
一个emoji表情对应一个utf8mb4字符。
一个emoji表情对应一张图片。
那么我们要做的就是,当这个字符被输入的时候,用一张图片代替。在android中Spannable可以显示很多东西,显示图片是没有问题的。
这是个体力活。还好有人已经做完了。在此感谢!

再说说数据库存储方面。
刚才已经说了,服务端不做任何修改,那么就需要在客户端把utf8mb4的编码转换一下,转换成普通字符,至少是普通的utf8,比如emoji字符 0x1f604 可以转换成[emoji]0x1f604[/emoji],这样就可以存储了,显示的时候再转换回去。

下面是我修改的部分,即,存入数据库前的转换和显示的时候的逆转换

private static final String emojiSeparatorStart = String.valueOf(Character.toChars(1));
private static final String emojiSeparatorEnd = "/" + String.valueOf(Character.toChars(1));

/**
 * Convert emoji characters of the given Spannable to the according
 * emojiCode for save for database.
 * 
 * @author wuwang(xzpv444@gmail.com)
 * 
 * @param context
 * @param text
 */
public static String convertEmojis(Context context, Spannable text) {
	String result = "";

	int index = 0;
	int length = -1;

	int textLength = text.length();
	int textLengthToProcessMax = textLength - index;
	int textLengthToProcess = length < 0 || length >= textLengthToProcessMax ? textLength : (length + index);

	// remove spans throughout all text
	EmojiconSpan[] oldSpans = text.getSpans(0, textLength, EmojiconSpan.class);
	for (int i = 0; i < oldSpans.length; i++) {
		text.removeSpan(oldSpans[i]);
	}

	int skip;
	for (int i = index; i < textLengthToProcess; i += skip) {
		skip = 0;
		int icon = 0;
		char c = text.charAt(i);
		if (isSoftBankEmoji(c)) {
			icon = getSoftbankEmojiResource(c);
			skip = icon == 0 ? 0 : 1;
		}
		int unicode = 0;
		if (icon == 0) {
			unicode = Character.codePointAt(text, i);
			skip = Character.charCount(unicode);

			if (unicode > 0xff) {
				icon = getEmojiResource(context, unicode);
			}

			if (icon == 0 && i + skip < textLengthToProcess) {
				int followUnicode = Character.codePointAt(text, i + skip);
				if (followUnicode == 0x20e3) {
					int followSkip = Character.charCount(followUnicode);
					switch (unicode) {
					case 0x0031:
						icon = R.drawable.emoji_0031;
						break;
					case 0x0032:
						icon = R.drawable.emoji_0032;
						break;
					case 0x0033:
						icon = R.drawable.emoji_0033;
						break;
					case 0x0034:
						icon = R.drawable.emoji_0034;
						break;
					case 0x0035:
						icon = R.drawable.emoji_0035;
						break;
					case 0x0036:
						icon = R.drawable.emoji_0036;
						break;
					case 0x0037:
						icon = R.drawable.emoji_0037;
						break;
					case 0x0038:
						icon = R.drawable.emoji_0038;
						break;
					case 0x0039:
						icon = R.drawable.emoji_0039;
						break;
					case 0x0030:
						icon = R.drawable.emoji_0030;
						break;
					case 0x0023:
						icon = R.drawable.emoji_0023;
						break;
					default:
						followSkip = 0;
						break;
					}
					skip += followSkip;
				} else {
					int followSkip = Character.charCount(followUnicode);
					switch (unicode) {
					case 0x1f1ef:
						icon = (followUnicode == 0x1f1f5) ? R.drawable.emoji_1f1ef_1f1f5 : 0;
						break;
					case 0x1f1fa:
						icon = (followUnicode == 0x1f1f8) ? R.drawable.emoji_1f1fa_1f1f8 : 0;
						break;
					case 0x1f1eb:
						icon = (followUnicode == 0x1f1f7) ? R.drawable.emoji_1f1eb_1f1f7 : 0;
						break;
					case 0x1f1e9:
						icon = (followUnicode == 0x1f1ea) ? R.drawable.emoji_1f1e9_1f1ea : 0;
						break;
					case 0x1f1ee:
						icon = (followUnicode == 0x1f1f9) ? R.drawable.emoji_1f1ee_1f1f9 : 0;
						break;
					case 0x1f1ec:
						icon = (followUnicode == 0x1f1e7) ? R.drawable.emoji_1f1ec_1f1e7 : 0;
						break;
					case 0x1f1ea:
						icon = (followUnicode == 0x1f1f8) ? R.drawable.emoji_1f1ea_1f1f8 : 0;
						break;
					case 0x1f1f7:
						icon = (followUnicode == 0x1f1fa) ? R.drawable.emoji_1f1f7_1f1fa : 0;
						break;
					case 0x1f1e8:
						icon = (followUnicode == 0x1f1f3) ? R.drawable.emoji_1f1e8_1f1f3 : 0;
						break;
					case 0x1f1f0:
						icon = (followUnicode == 0x1f1f7) ? R.drawable.emoji_1f1f0_1f1f7 : 0;
						break;
					default:
						followSkip = 0;
						break;
					}
					skip += followSkip;
				}
			}
		}

		if (icon > 0) {
			result += emojiSeparatorStart + Integer.toHexString(unicode) + emojiSeparatorEnd;
		} else {
			result += c;
		}
	}
	return result;
}

/**
 * restore emojiCode to emoji character
 * 
 * @author wuwang(xzpv444@gmail.com)
 * 
 * @param context
 * @param text
 * @return
 */
public static CharSequence restoreEmojis(Context context, CharSequence text) {
	String regexp = emojiSeparatorStart + ".*?" + emojiSeparatorStart;
	Pattern p = Pattern.compile(regexp);
	Matcher m = p.matcher(text);
	while (true) {
		if (m.find()) {
			String x = String.valueOf(Character.toChars(Integer.valueOf(m.group(0).replace(emojiSeparatorEnd, "").replace(emojiSeparatorStart, ""), 16)));
			text = text.toString().replace(m.group(0), x);
		} else {
			break;
		}
	}
	return text;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Android 中实现 emoji 表情选择的 View,一般可以采用以下两种方式: 1. 使用第三方库 可以使用一些开源的第三方库,如: - Emoji-Keyboard:https://github.com/rockerhieu/emojicon - EmojiEditText:https://github.com/kimoBiko/EmojiEditText - EmojiCompat:https://developer.android.com/topic/libraries/support-library/packages#emoji-compat 这些库都提供了丰富的 emoji 表情选择界面和相关的实现方法,可以方便地集成到项目中。 2. 自定义 View 如果需要更灵活地实现 emoji 表情选择的 View,可以自己实现一个自定义 View。具体实现步骤如下: 1. 准备 emoji 表情资源 首先需要准备 emoji 表情的资源,可以自己设计或者使用现成的资源。将这些资源放在项目的 res 目录下。 2. 自定义 View 自定义 View 可以继承自 LinearLayout,包含一个 EditText 和一个 GridView。 在 EditText 的右侧添加一个按钮,点击按钮时显示 emoji 表情选择的 GridView,点击表情后将表情插入到 EditText 中。 3. 实现表情选择的 GridView GridView 中的每个表情可以使用 ImageView 显示,可以通过设置表情资源的 ID 来显示不同的表情。在表情选择界面的底部可以添加一个删除按钮,点击删除按钮可以删除 EditText 中的最后一个字符或者最后一个表情。 4. 实现点击表情插入到 EditText 的功能 当用户点击 GridView 中的表情时,可以将表情插入到 EditText 中。可以通过在 EditText 中插入一个 SpannableString 来实现,其中 SpannableString 中包含了表情的资源 ID。 以上就是实现 emoji 表情选择的 View 的一般步骤,可以根据具体需求进行自定义实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值