新浪微博的表情实现

关于表情的实现,sdk里面也提供一个表情的解析类,SmileyParser,,可以利用这个类来处理表情的。

它主要是构造了一个SpannableStringBuilder,然后里面添加ImageSpan,虽然打印出来的字符串与没有经过处理的一样,但经过这个处理后就可以显示图片了,有了ImageSpan,才有表情的显示。



关于微博的表情,可以从api里面下载。表情的格式大概是:

[{"phrase":"[织]","type":"face","url":"http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/41/zz2_org.gif","hot":false,"common":true,"category":"","icon":"http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/41/zz2_thumb.gif","value":"[织]","picid":""},

{"phrase":"[神马]",
"type":"face",
"url":"http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/60/horse2_org.gif",
"hot":false,
"common":true,
"category":"",
"icon":"http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/60/horse2_thumb.gif",
"value":"[神马]",
"picid":""},。。。这样的形式,

表情数量太多了,只解析 "common":true的,就是常用的表情。把里面的图片下载下来就可以用了。 

需要注意的是你的 "phrase":"[织]"这个名字不能随意地更改。关于这个名字对应什么图片是自己控制的,但不保证在其它的程序是显示正常。 

于是我就用一个map来存储:

public static final HashMap<String, Integer> mSmileyMap=new HashMap<String, Integer>();

static {
mSmileyMap.put("[织]", Integer.valueOf(R.drawable.zz2_org));
mSmileyMap.put("[神马]", Integer.valueOf(R.drawable.horse2_org));
mSmileyMap.put("[浮云]", Integer.valueOf(R.drawable.fuyun_org));
mSmileyMap.put("[给力]", Integer.valueOf(R.drawable.geili_org));
mSmileyMap.put("[围观]", Integer.valueOf(R.drawable.wg_org));
mSmileyMap.put("[威武]", Integer.valueOf(R.drawable.vw_org));
mSmileyMap.put("[熊猫]", Integer.valueOf(R.drawable.panda_org));
mSmileyMap.put("[兔子]", Integer.valueOf(R.drawable.rabbit_org));
mSmileyMap.put("[奥特曼]", Integer.valueOf(R.drawable.otm_org));
mSmileyMap.put("[囧]", Integer.valueOf(R.drawable.j_org));

。。。。其它不列出了。上面下载的是原始图片,如果要缩略图可以用 thumb.gif下载 。



然后开始构造表情的解析类:

单例。

构造 。

private AKSmileyParser(Context context) {
mContext=context;
mSmileyTexts=AKSmiley.mSmileyMap.keySet().toArray(new String[0]);
System.out.println("AKSmileyParser:"+mSmileyTexts+" ssm:"+AKSmiley.mSmileyMap.size());
mPattern=buildPattern();
} 

private Pattern buildPattern() {
int length=AKSmiley.mSmileyMap.size();
// Set the StringBuilder capacity with the assumption that the average
// smiley is 3 characters long.
StringBuilder patternString=new StringBuilder(length*3);

System.out.println("buildPattern:"+mSmileyTexts);
// Build a regex that looks like (:-)|:-(|...), but escaping the smilies
// properly so they will be interpreted literally by the regex matcher.
patternString.append("(");
for (String s : mSmileyTexts) {
patternString.append(Pattern.quote(s));
patternString.append('|');
}
// Replace the extra '|' with a ')'
patternString.replace(patternString.length()-1, patternString.length(), ")");

return Pattern.compile(patternString.toString());
}

然后就可以使用了。

初始化:

AKSmileyParser parser=AKSmileyParser.getInstance(this);

用gridview来显示表情。其中

holder.appImage.setImageDrawable(context.getResources().getDrawable(AKSmiley.mSmileyMap.get(list[index]))); 显示图片。


  private String[] list;//这个东西就是表情的key


@Override
public Object getItem(int index) {
return list[index];
}

初始化适配器:mAdapter.setList(AKSmileyParser.getInstance(this).mSmileyTexts);

表情显示成功了:

设置setOnItemClickListener事件:

String oldChar=edit_text.getText().toString();
  Log.d(TAG, "oldChar:"+oldChar);//原始字符

String charToBuild=(String) mAdapter.getItem(position);
  Log.d(TAG, "charToBuild:"+charToBuild);//新加入的字符,这个字符就是用map中的key:[神马]形式的

  int selection=edit_text.getSelectionStart();//需要知道当前选中的位置,因为表情是ImageSpan,不是字符串,所以选中的位置会不正确。
  CharSequence start=oldChar.subSequence(0, selection);//选中位置的开始点,从0开始
CharSequence end=oldChar.subSequence(selection, oldChar.length());
Log.d(TAG, "start:"+start+"---end:"+end+" selection:"+selection);

StringBuilder builder=new StringBuilder(start);
builder.append(charToBuild).append(end);//构造新的字符串,虽然表情用ImageSpan显示,但字符串的内容还是一样的。
int newSel=selection+charToBuild.length();//计算新的选中的光标位置,

AKSmileyParser parser=AKSmileyParser.getInstance(this);
  CharSequence newChar=parser.addSmileySpans(builder);//解析新的字符串,如果只解析新添加的部分,其它的还是会显示成字符串“[神马]”这样的,所以需要重新解析所有的

Log.d(TAG, "newChar:"+newChar+" newSel:"+newSel);

edit_text.setText(newChar);
edit_text.setSelection(newSel);//设置光标的新位置。
txt_text.setText(newChar);
日志显示:
//09-27 11:05:07: D: oldChar:神马[神马] d兔子[兔子]ad嘻嘻[嘻嘻]aa
//09-27 11:05:07: D: charToBuild:[哈哈]
//09-27 11:05:07: D: start:神马[神马] d兔---end:子[兔子]ad嘻嘻[嘻嘻]aa selection:9//在兔子中间插入
//09-27 11:05:07: D: newChar:神马[神马] d兔[哈哈]子[兔子]ad嘻嘻[嘻嘻]aa newSel:13

apk下载,源码暂时没有。稍后提供。上面已经提供了大多数了,部分不全的代码自己补全。




猜你喜欢

转载自phenom.iteye.com/blog/1686742
今日推荐