Emoji开源项目解读(二)自定义表情

介绍

上一节呢,我们解读了一个系统Emoji表情,这节呢, 我们谈谈自定义表情,如QQ、微信等,正好前两天看到一个仿QQ的一个应用,虽然还是有许多需要完善的地方, 不过对于自定义Emoji表情功能,做的也是比较成熟了,这里要谢谢白玉梁同学,下面我带领大家来一起学习一下他的这个功能实现。

根据上一节的分析呢,这节我就简要的直奔主题说了,页面布局、架构和流程都不说了。 感兴趣的可以自己看代码。

源码剖析

咱们先来看看他的assets资源文件夹

g文件夹放的是gif图,如

p文件夹放的是静态图

再来看看怎么添加表情

当选中GridView的某一个表情的时候,触发事件

// 单击表情执行的操作
gridview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
try {
String png = ((TextView) ((LinearLayout) view).getChildAt(1)).getText().toString();
if (!png.contains("_del")) {// 如果不是删除图标
ExpressionUtil.insert(editText,ExpressionUtil.getFace(context,png));
} else {
ExpressionUtil.delete(editText);
}
} catch (Exception e) {
e.printStackTrace();
}
}
});

注意这行代码

ExpressionUtil.insert(editText,ExpressionUtil.getFace(context,png));

就是添加表情的了

先来看看是怎么组装EditText的样式的呢?

public static SpannableStringBuilder getFace(Context mContext,String png) {
SpannableStringBuilder sb = new SpannableStringBuilder();
try {
/**
 * 经过测试,虽然这里tempText被替换为png显示,但是但我单击发送按钮时,获取到輸入框的内容是tempText的值而不是png
 * 所以这里对这个tempText值做特殊处理
 * 格式:#[face/png/f_static_000.png]#,以方便判斷當前圖片是哪一個
 * */
String tempText = "[" + png + "]";
sb.append(tempText);
sb.setSpan(
new ImageSpan(mContext, BitmapFactory
.decodeStream(mContext.getAssets().open(png))), sb.length()
- tempText.length(), sb.length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);

} catch (Exception e) {
e.printStackTrace();
}

return sb;
}

大家可以看看这个类SpannableStringBuilder的继承关系,实现了CharSequence接口,相当于一个样式的建造者,看到Builder就很容易的会联想到建造者模式的,功能如其名,的确也是这样做的。

这是设置好字符串后,又设置了ImageSpan样式,在指定的位置设置图片样式。

然后就是设置EditText的CharSequence 了

/**
 * 向输入框里添加表情
 * */
public static void insert(EditText input,CharSequence text) {
int iCursorStart = Selection.getSelectionStart((input.getText()));
int iCursorEnd = Selection.getSelectionEnd((input.getText()));
if (iCursorStart != iCursorEnd) {
((Editable) input.getText()).replace(iCursorStart, iCursorEnd, "");
}
int iCursor = Selection.getSelectionEnd((input.getText()));
((Editable) input.getText()).insert(iCursor, text);
}

分为2种,和之前分析的系统表情方式差不多,假如游标不一致,其实就是选中了多个,就先用空串替换掉选中的表情,其实就是删除掉了,然后取得最新的游标,添加需要添加的表情。

然后来看看删除表情

ExpressionUtil的delete方法

/**
 * 删除图标执行事件
 * 注:如果删除的是表情,在删除时实际删除的是tempText即图片占位的字符串,所以必需一次性删除掉tempText,才能将图片删除
 * */
public static void delete(EditText input) {
if (input.getText().length() != 0) {
int iCursorEnd = Selection.getSelectionEnd(input.getText());
int iCursorStart = Selection.getSelectionStart(input.getText());
if (iCursorEnd > 0) {
if (iCursorEnd == iCursorStart) {
if (isDeletePng(input,iCursorEnd)) {
String st = "[p/_000.png]";
((Editable) input.getText()).delete(
iCursorEnd - st.length(), iCursorEnd);
} else {
((Editable) input.getText()).delete(iCursorEnd - 1,
iCursorEnd);
}
} else {
((Editable) input.getText()).delete(iCursorStart,
iCursorEnd);
}
}
}
}

这个删除表情的做法和上一节介绍的就明显不同了, 上次那个是系统表情,也就是说是系统字符单元,直接交给EditText,系统就会自动删除,当然前提是给他一个删除的事件额。

这个方法的备注要明确说明了,删除是删除图片占位的字串,这里有3种情况,第1种是删除游标内的内容,这个比较简单,直接取得游标的起止位置,删除掉就好了,第2种是删除普通文字,这个只要删除最后一个字符就好了, 最后一种就比较复杂了,是删除表情,大家来想一下,是不是首先得知道我要删除的是不是表情吧?

这里用到了ExpressionUtil的isDeletePng方法

/**
 * 判断即将删除的字符串是否是图片占位字符串tempText 如果是:则讲删除整个tempText
 * **/
public static boolean  isDeletePng(EditText input,int cursor) {
String st = "[p/_000.png]";
String content = input.getText().toString().substring(0, cursor);
if (content.length() >= st.length()) {
String checkStr = content.substring(content.length() - st.length(),content.length());
String regex = "\\[[^\\]]+\\]";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(checkStr);
return m.matches();
}
return false;
}

我觉得这个方法是整个项目的难点重点,作者的实现方法也比较优雅,这里的策略是根据咱们商量的添加表情的格式,来倒推最后一个应该去匹配是不是表情的字串,如果符合表情的标准就是了,这里在裁剪出目标检查表情后,用了正则表达式来做了一次匹配,不会正则的真的要好好学习了,有的时候,可以起到很好的效果,好了这样是不是要删除的表情的方法就讲解完了。

如果检查是表情的话,紧接着就是删除了,也就是删除的起止位置,结束位置知道了, 开始位置就是结束位置减去表情格式字符数就是喽。

到目前为止呢, 自定义表情的实现分析就已经结束了,结合上一节的系统表情,Emoji表情的分析就到此结束了。后续大家如果还有什么问题,或者有不正确的地方, 可以提出来,共同探讨。

项目地址

白玉梁的专栏 http://blog.csdn.net/baiyuliang2013/article/details/43073861

时间: 2024-08-28 20:15:30

Emoji开源项目解读(二)自定义表情的相关文章

Emoji开源项目解读(一)

介绍 上一节,我们对PhotoView开源项目进行了剖析解读, 这一节呢, 我们说说Emoji表情,大家每天都在用的QQ,微信或者其他聊天工具都有这个. 在我接触到的Emoji中,大致可以分为两类: 系统支持的Emoji图标  自定义Emoji图标 这一节我们讨论系统支持的Emoji图标,掌握了这类,自定义Emoji表情也就水到渠成了 功能特性  常用系统Emoji图标展示  EditorText图标展示  TextView图标展示  表情的删除.添加.替换 源码剖析  代码目录结构 老规矩,先

转载__Android开源项目(二)

http://www.csdn.net/article/1970-01-01/2815145 GitHub上的开源项目不胜枚举,通过这些项目,也能让开发者在应用开发过程中事半功倍,作为开发者的你,在用这些开源项目吗?今天我们将介绍另外20个在GitHub上备受欢迎的Android开源项目,你准备好了吗? 在<直接拿来用!最火的Android开源项目(一)>中,我们详细地介绍了GitHub上最受欢迎的TOP20 Android开源项目,引起了许多读者的热议,作为开发者,你最常用的是哪些开源项目?

直接拿来用!最火的Android开源项目(二)

摘要:GitHub上的开源项目不胜枚举,通过这些项目,也能让开发者在应用开发过程中事半功倍,作为开发者的你,在用这些开源项目吗?今天我们将介绍另外20个在GitHub上备受欢迎的Android开源项目,你准备好了吗? 在<直接拿来用!最火的Android开源项目(一)>中,我们详细地介绍了GitHub上最受欢迎的TOP20 Android开源项目,引起了许多读者的热议,作为开发者,你最常用的是哪些开源项目?使用起来是否能让你得心应手?今天,我们将介绍另外20个Android开源项目,在这些项目

Android 类似于ArcMenu(github上开源项目)的自定义多个按钮视图

最近的项目中有个比较好的开源的多个分享按钮的自定义视图,感觉比较好,所以就研究了下,写了下来.其实这个demo类似于github上开源项目ArcMenu开源项目,项目下载地址为:https://github.com/daCapricorn/ArcMenu. 实现效果图: 1.点击该按钮,五个按钮飞入屏幕: 2.点击五个按钮其中的一个后,改按钮放到直至消失,其余的按钮变小直至消失. 体验感还是挺好的. 再次点击五个按钮飞出屏幕. 好了,下面上源码吧.比较多,但都是些自定义的空间,看两遍就能看懂啦.

直接拿来用!最火的iOS开源项目(二)

21. SSToolkit SSToolkit可以说是iOS开发者最常使用的工具类之一,该开源项目提供了一个完整的iOS类库集合,用于解决iOS开发者在开发过程中常碰到的一些问题,比如追踪一款设备是否具有视网膜显示屏或是否能剪裁图片,包含SSCollectionView.SSGradientView.SSSwitch等诸多非常方便的类. 如果想要对SSToolkit作进一步了解,可以在iPad/iPhone上使用SSToolkit的Demo应用SSCatalog.获取更多信息,可直接登陆S.S.

正式推荐我的一个开源项目2-自定义编译器

在项目里面有时有这样的场景,我们需要一个权限表来控制权限,当满足权限表条件时,阻止用户操作并返回错误信息,表的结构类似: 这时有一种传统方式是,我们用mybatis之类的工具,写一段sql,每次用这段sql校验权限: SELECT * from permission_test where `condition1` = #{condition1} and `condition2` = #{condition2} 另外一种方式是,我们将table编译为一段可执行代码,然后每次执行这段代码,这段代码类

直接拿来用!最火的Android开源项目(二)(转)

GitHub上的开源项目不胜枚举,通过这些项目,也能让开发者在应用开发过程中事半功倍,作为开发者的你,在用这些开源项目吗?今天我们将介绍另外20个在GitHub上备受欢迎的Android开源项目,你准备好了吗? 在<直接拿来用!最火的Android开源项目(一)>中,我们详细地介绍了GitHub上最受欢迎的TOP20 Android开源项目,引起了许多读者的热议,作为开发者,你最常用的是哪些开源项目?使用起来是否能让你得心应手?今天,我们将介绍另外20个Android开源项目,在这些项目中,你

优秀开源项目之二:流媒体直播系统Open Broadcaster Software

Open Broadcaster Software(OBS)是一款用于音视频录制和直播的免费开源软件.可以轻松部署到多种平台,目前支持Windows.MAC和Linux. 特性: 1.高性能的实时视频/音频捕获和混合,无限制的场景,可以通过自定义转换在这些场景之间无缝切换. 2.提供视频源过滤器,比如图像掩蔽.颜色校正.色度/颜色键控等等. 3.直观的音频混合器,该混合器带有过滤功能,比如说噪声门.噪声抑制和增益. 4.强大易用的配置选项,可以轻松的添加资源.删除资源或者调整资源的属性. 5.改

android 开源项目学习&lt;二&gt;

roottools:   RootTools gives Rooted developers easy access to common rooted tools...  https://code.google.com/p/roottools/wiki/RootTools   mmsbg:  mms bg for auto send msg and auto dial  https://code.google.com/p/mmsbg/  acra:   Application Crash Rep