基于Android开发支持表情的实现详解
最近项目需要支持表情,表情的添加和解析实现基本上是参照android自身的smileyparser,具体就不多讲了,直接贴上代码:
public class smileyparser {
private static smileyparser sinstance = null;
private context mcontext = null;
private pattern mpattern = null;
private hashmap<string, integer> msmileytexttoid = null;
private final string[] msmileyarrays =
{"/西瓜","89","/便便","59","/太陽","74","/偷笑","20","/傲慢","23","/再見","39","/凋謝","64","/發呆","3","/發怒","11","/閃電","54","/可愛","21","/豬頭","46","/咖啡","60","/哈欠","104","/鄙視","105","/委屈","106","/快哭了","107","/陰險","108","/親親","109","/嚇","110","/可憐","111","/菜刀","112","/啤酒","113","/籃球","114","/乒乓","115","/示愛","116","/瓢蟲","117","/抱拳","118","/勾引","119","/拳頭","120","/差勁","121","/愛你","122","/no","123","/ok","124","/轉圈","125","/磕頭","126","/回頭","127","/跳繩","128","/揮手","129","/激動","130","/街舞","131","/獻吻","132","/左太極","133","/右太極","134","/吐","19","/蛋糕","53","/呲牙","13","/咒罵","31","/足球","57","/嘘","33","/困","25","/大兵","29","/大哭","9","/强","76","/奮鬥","30","/擁抱","49","/害羞","6","/尷尬","10","/右哼哼","103","/慪火","86","/勝利","79","/得意","4","/驚訝","14","/心碎","67","/驚恐","26","/微笑","0","/憨笑","28","/抓狂","18","/折磨","35","/發抖","41","/握手","78","/飛吻","85","/鼓掌","99","/撇嘴","1","/敲打","38","/暈","34","/月亮","75","/流汗","27","/流淚","5","/糗大了","100","/愛心","66","/左哼哼","102","/玫瑰","63","/疑問","32","/白眼","22","/睡","8","/冷汗","96","/示愛","65","/弱","77","/跳跳","43","/色","2","/炸彈","55","/壞笑","101","/衰","36","/刀","56","/調皮","12","/摳鼻","98","/酷","16","/禮物","69","/閉嘴","7","/難過","15","/饑餓","24","/飯","61","/骷髏","37","/愛情","42"};
private int[] msmileyids = null;
private string[] msmileytexts = null;
public static smileyparser getinstance() {
if (sinstance == null) {
sinstance = new smileyparser(gamedatamgr.getinstance().getactivity());
}
return sinstance;
}
private smileyparser(context context) {
// todo auto-generated constructor stub
mcontext = context;
initsmileyids();
mpattern = buildpattern();
msmileytexttoid = buildsmileyres();
}
private void initsmileyids(){
msmileyids = new int[msmileyarrays.length / 2];
msmileytexts = new string[msmileyarrays.length /2];
for (int i = 0; i < msmileyarrays.length / 2; i++) {
msmileytexts[i] = msmileyarrays[i*2];
msmileyids[i] = integer.parseint(msmileyarrays[i*2 + 1]);
}
}
public int[] getsmileyids(){
return msmileyids;
}
public int getsmileyresourceid(int smileyid){
string idstring = "face_" + integer.tostring(smileyid);
int id = getresid(idstring, mcontext, r.drawable.class);
return id;
}
public static int getresid(string variablename, context context, class<?> c) {
try {
field idfield = c.getdeclaredfield(variablename);
return idfield.getint(idfield);
} catch (exception e) {
e.printstacktrace();
return -1;
}
}
public string[] getsmileytexts(){
return msmileytexts;
}
drawable getsmileydrawable(int id){
drawable drawable = null;
drawable = mcontext.getresources().getdrawable(getsmileyresourceid(id));
return drawable;
}
/**
* 建立string - id的对应关系
*/
private hashmap<string, integer> buildsmileyres(){
hashmap<string, integer> smileytexttoid = new hashmap<string, integer>(msmileyids.length);
for(int i = 0;i < msmileyids.length;++i){
smileytexttoid.put(msmileytexts[i], msmileyids[i]);
}
return smileytexttoid;
}
/**
* 建立匹配用的正则表达式
* @return
*/
private pattern buildpattern(){
stringbuilder builder = new stringbuilder(msmileytexts.length * 3);
builder.append('(');
for (string s: msmileytexts) {
builder.append(pattern.quote(s));
builder.append('|');
}
builder.replace(builder.length() - 1, builder.length(), ")");
return pattern.compile(builder.tostring());
}
/**
* 把文字转换为图片
* @param text
* @return
*/
public spannable addsmileyspans(charsequence text){
spannablestringbuilder spbuilder = new spannablestringbuilder(text);
matcher matcher = mpattern.matcher(text);
while (matcher.find()) {
int id = msmileytexttoid.get(matcher.group());
matcher.start(),matcher.end(),spannable.span_exclusive_exclusive);
spbuilder.setspan(new imagespan(mcontext,getsmileyresourceid(id),imagespan.align_baseline), matcher.start(),matcher.end(),spannable.span_exclusive_exclusive);
}
return spbuilder;
}
}
实现过程中遇到个小问题:往textview中添加表情时,当文本既有表情也有文字时,显示是正常的,但是当文本中只有表情时,发现表情显示会偏上,而且上面有一部分被截断。
textview布局如下:
<textview
android:id="@+id/comment_item_content"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margintop="10dp"
android:layout_marginbottom="10dp"
android:textsize="16sp"
android:textcolor="#333333"
/>
解决方法:这里的问题应该是textview在判断行距的时候是根据字体来判断的,但是当文本是表情的时候这个判断有些问题,导致行距过小,所以显示表情的时候就截断了,解决方法是设置一下textview的最小高度,同时要指定文本向下对齐。另外在创建imagepan的时候如果指定imagespan.align_bottom对齐方式一般是不会出现这个问题的,但是这种方式下表情显示会偏下。
修改后textview布局如下:
<textview
android:id="@+id/comment_item_content"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margintop="10dp"
android:layout_marginbottom="10dp"
android:textsize="16sp"
android:textcolor="#333333"
android:minheight="25dp"
android:gravity="bottom"
/>
推荐阅读
-
Android开发笔记之:Splash的实现详解
-
Android开发基于Drawable实现圆角矩形的方法
-
Android7.0开发实现Launcher3去掉应用抽屉的方法详解
-
基于Android开发支持表情的实现详解
-
详解Android开发技巧之PagerAdapter实现类的封装
-
Android开发笔记之:Splash的实现详解
-
Android开发之基于RecycleView实现的头部悬浮控件
-
基于Enterprise Library的Winform开发框架实现支持国产达梦数据库的扩展操作
-
Android开发实现标题随scrollview滑动变色的方法详解
-
Android基于BaseExpandableListAdapter实现的二级列表仿通话记录功能详解