android 开源表情输入,[Android开源]Emoji开源项目解读(一)系统表情
介绍上一节,我们对PhotoView开源项目进行了剖析解读,这一节呢,我们说说Emoji表情,大家每天都在用的QQ,微信或者其他聊天工具都有这个。在我接触到的Emoji中,大致可以分为两类:系统支持的Emoji图标自定义Emoji图标这一节我们讨论系统支持的Emoji图标,掌握了这类,自定义Emoji表情也就水到渠成了功能特性常用系统Emoji图标展示EditorText图标展示TextVie..
介绍
上一节,我们对PhotoView开源项目进行了剖析解读, 这一节呢, 我们说说Emoji表情,大家每天都在用的QQ,微信或者其他聊天工具都有这个。
在我接触到的Emoji中,大致可以分为两类:
系统支持的Emoji图标
自定义Emoji图标
这一节我们讨论系统支持的Emoji图标,掌握了这类,自定义Emoji表情也就水到渠成了
功能特性
常用系统Emoji图标展示
EditorText图标展示
TextView图标展示
表情的删除、添加、替换
源码剖析
代码目录结构
老规矩,先上代码结构图,有个总体的认识
样例
做一个插入表情的流程例子
setContentView(R.layout.activity_main);
mEditEmojicon = (EditText) findViewById(R.id.editEmojicon);
mTxtEmojicon = (TextView) findViewById(R.id.txtEmojicon);
mEditEmojicon.addTextChangedListener(new TextWatcherAdapter() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
mTxtEmojicon.setText(s);
}
});时序图
好了,上面是表情变化的一个调用流程,基本流程就是EmojiconsFragment里面的图标点击事件或者返回事件,回调一下, 让客户端来调用EmojiconEditText增删表情,然后监听EmojiconEditText的文本变化事件,来设置EmojiconTextView的文本, 这里都用到了EmojiconHandler这个类,他是表情的逻辑核心处理类,表情的管理都在这了。 我们的重点也在这了。
插入表情
我们看到在例子中是在回调方法中,调用的插入方法
@Override
public void onEmojiconClicked(Emojicon emojicon) {
EmojiconsFragment.input(mEditEmojicon, emojicon);
}然后跟进去看到public static void input(EditText editText, Emojicon emojicon) {
if (editText == null || emojicon == null) {
return;
}
int start = editText.getSelectionStart();
int end = editText.getSelectionEnd();
if (start
editText.append(emojicon.getEmoji());
} else {
editText.getText().replace(Math.min(start, end), Math.max(start, end), emojicon.getEmoji(), 0, emojicon.getEmoji().length());
}
}这里看有没有选中文本或者有游标,如果没有就在后面加上表情就好了,如果有的话,就替换指定位置的文本。
删除表情
看代码@Override
public void onEmojiconBackspaceClicked(View v) {
EmojiconsFragment.backspace(mEditEmojicon);
}进去在看public static void backspace(EditText editText) {
KeyEvent event = new KeyEvent(0, 0, 0, KeyEvent.KEYCODE_DEL, 0, 0, 0, 0, KeyEvent.KEYCODE_ENDCALL);
editText.dispatchKeyEvent(event);
}这里直接生成了一个删除的按键实例,让EditText执行,就行了。 代码比较简洁有效,为什么这样可以呢?别急,看下面慢慢说明。
EmojiconEditText
然后,我们在来看看EmojiconEditText中,对于文字变化后的逻辑是怎么处理的?也是关键地方所在。
看代码
@Override
protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
EmojiconHandler.addEmojis(getContext(), getText(), mEmojiconSize);
}又是EmojiconHandler来做的处理,跟进去public static void addEmojis(Context context, Spannable text, int emojiSize) {
int length = text.length();
EmojiconSpan[] oldSpans = text.getSpans(0, length, EmojiconSpan.class);
for (int i = 0; i
text.removeSpan(oldSpans[i]);
}
int skip;
for (int i = 0; i
//中间省略......
text.setSpan(new EmojiconSpan(context, icon, emojiSize), i, i + skip, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}总体思路是这样的,先删除Spannable中的样式,然后在解析表情,添加样式,在增删样式对象中我们看到了EmojiconSpan,这么个东东?它又是干啥的呢?
EmojiconSpan
可能有的童靴对样式这些比较迷糊, 好的, 为了有一个清晰的认识, 我画了一个类图,可以很明了的知道他们的关系.
看看EmojiconSpan在什么等级上面,其实和ImageSpan是一个级别的,一种样式而已,从上图也可以了解到真正的跟样式打交道的,也不是EditText而是Editable。这样设计,文本和样式是分离的,耦合度比较低,还是不错的。呵呵。
再来看看EmojiconSpan的重写方法public Drawable getDrawable() {
if (mDrawable == null) {
try {
mDrawable = mContext.getResources().getDrawable(mResourceId);
int size = mSize;
mDrawable.setBounds(0, 0, size, size);
} catch (Exception e) {
// swallow
}
}
return mDrawable;
}那么在添加表情的时候,资源id是怎么来的呢?
大家在EmojiconHandler里面可以看到有两个属性集合,存放emoji和softbank表情的private static final SparseIntArray sEmojisMap = new SparseIntArray(846);
private static final SparseIntArray sSoftbanksMap = new SparseIntArray(471);然后在静态块中进行了初始化操作static {
// People
sEmojisMap.put(0x1f604, R.drawable.emoji_1f604);
sEmojisMap.put(0x1f603, R.drawable.emoji_1f603);
//省略......
}后面添加的值我们很容易理解,是资源id,前面的16进制数值Key是个什么东东呢?
这个值是随意定义的Key吗?这个还真不是,呵呵。经过查资料得知,这个还是有一套标准的。对,Emoji也是有标准的。
咱们来举个例子吧,阳光图标吧
对应代码sEmojisMap.put(0x2600, R.drawable.emoji_2600);
sSoftbanksMap.put(0xe04a, R.drawable.emoji_2600);大家找到对应关系了吗?对的,前面的是Symbol 标准,后面的是softbank标准,google都支持。
删除表情再议
这个在系统emoji中,程序处理比较简单,直接给EmojiconEditText一个删除的按键事件就解决了,正如上面说的那样,为什么这样做可以呢?归根到底还是因为他是系统的emoji,系统本身就可以识别这个编码,他当做一个东东来处理了,就像一个文字字符一样,如果是自定义emoji就没那么简单了,需要自己进行单独处理,下一节将会接触到这个。
好了,系统Emoji表情就说到这了,主要是EditText的操作,文本样式的应用,系统Emoji编码知识,小知识点还是蛮多的。后续大家如果还有什么问题,或者有不正确的地方, 可以提出来,共同探讨。
Github
https://github.com/rockerhieu/emojicon
Emoji图标编码
更多推荐
所有评论(0)