欢迎来到代码驿站!

Android代码

当前位置:首页 > 移动开发 > Android代码

基于Android开发支持表情的实现详解

时间:2021-05-05 15:35:38|栏目: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","/凋?x","64","/?l呆","3","/?l怒","11","/?W?","54","/可??","21","/?i?^","46","/咖啡","60","/哈欠","104","/鄙?","105","/委屈","106","/快哭了","107","/??U","108","/?H?H","109","/??","110","/可?z","111","/菜刀","112","/啤酒","113","/?@球","114","/乒乓","115","/示??","116","/瓢?x","117","/抱拳","118","/勾引","119","/拳?^","120","/差??","121","/?勰?","122","/NO","123","/OK","124","/?D圈","125","/磕?^","126","/回?^","127","/跳?K","128","/?]手","129","/激??","130","/街舞","131","/?I吻","132","/左太?O","133","/右太?O","134","/吐","19","/蛋糕","53","/呲牙","13","/咒?R","31","/足球","57","/嘘","33","/困","25","/大兵","29","/大哭","9","/强","76","/?^?Y","30","/?肀?","49","/害羞","6","/?擂?","10","/右哼哼","103","/?Y火","86","/?倮?","79","/得意","4","/?@?","14","/心碎","67","/?@恐","26","/微笑","0","/憨笑","28","/抓狂","18","/折磨","35","/?l抖","41","/握手","78","/?w吻","85","/鼓掌","99","/撇嘴","1","/敲打","38","/??","34","/月亮","75","/流汗","27","/流?I","5","/糗大了","100","/?坌?","66","/左哼哼","102","/玫瑰","63","/疑??","32","/白眼","22","/睡","8","/冷汗","96","/示??","65","/弱","77","/跳跳","43","/色","2","/炸??","55","/?男?","101","/衰","36","/刀","56","/?{皮","12","/?副?","98","/酷","16","/?Y物","69","/?]嘴","7","/?y?^","15","/??I","24","/?","61","/骷?t","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 中Lambda表达式的使用实例详解

栏    目:Android代码

下一篇:详解Android OkHttp完全解析

本文标题:基于Android开发支持表情的实现详解

本文地址:http://www.codeinn.net/misctech/115024.html

推荐教程

广告投放 | 联系我们 | 版权申明

重要申明:本站所有的文章、图片、评论等,均由网友发表或上传并维护或收集自网络,属个人行为,与本站立场无关。

如果侵犯了您的权利,请与我们联系,我们将在24小时内进行处理、任何非本站因素导致的法律后果,本站均不负任何责任。

联系QQ:914707363 | 邮箱:codeinn#126.com(#换成@)

Copyright © 2020 代码驿站 版权所有