在Android中支持表情

通过admin

在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”

/>

关于作者

admin administrator

发表评论