基于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"

/>

(0)

相关推荐

  • android高仿微信表情输入与键盘输入代码(详细实现分析)

    表情与键盘的切换输入大部分IM都会需要到,之前自己实现了一个,还是存在些缺陷,比如说键盘与表情切换时出现跳闪问题,这个困扰了我些时间,不过所幸在Github(其代码整体结构很不错)并且在论坛上找些解决思路,再加上研究了好几个开源项目的代码,最后终于苦逼地整合出比较不错的实现效果(这里不仅给出了实现方案,还提供一个可拓展的fragment模板以便大家实现自己的表情包)代码我已进行另外的封装与拓展,大家需要其他表情的话只需要根据fragment模板实现自己的表情界面,然后根据工厂类获取即可,实现效果

  • Android编程开发实现TextView显示表情图像和文字的方法

    本文实例讲述了Android编程开发实现TextView显示表情图像和文字的方法.分享给大家供大家参考,具体如下: 从这个案例中我们可以学到当我们美化图片美化界面的时候可以在某一区域输入图片和文字混搭信息,第三张图片按比例缩小,第四张图像有超链接 布局文件 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.andro

  • 完整的Android表情功能处理方案

    Android表情功能处理方案概述 1.原理和实现思路 2.表情图片显示 3.表情面板 4.表情的输入框插入和删除 5.表情添加脚本 Android中表情功能,一般都不是用ImageView去设置图片实现的,表情一般会嵌套在文本之中,那么如何实现呢,这里就介绍一下其中的原理,此外还有相关功能的实现思路和具体代码. 先看下良心动态图 1.原理和思路 a.表情内容的数据格式 表情看上去是图片,但是在数据传输的时候本质上是一个特殊文本: 比如QQ表情就是一个 "/表情字母"的结构,比如害羞的

  • Android编程实现QQ表情的发送和接收完整实例(附源码)

    本文实例讲述了Android编程实现QQ表情的发送和接收.分享给大家供大家参考,具体如下: 在自己做一个聊天应用练习的时候,需要用到表情,于是就想着模仿一下QQ表情,图片资源完全copy的QQ.apk,解压就可以得到,这里不细说. 下面将该应用中的表情模块功能抽离出来,以便自己以后复习回顾.. 先看一下效果图: 首先进入界面:(完全仿照QQ) 点击一下上面的表情图标: 选择一些表情,输入一些文字混合: 点击发送: 可以看到文字和表情图片都一起显示出来了. 下面列出一些关键代码: 表情工具类Exp

  • Android输入框添加emoje表情图标的实现代码

    前言 再次写聊天的时候才发现,代码积累是一件非常重要的事情,就如这篇博客的意图其实就是代码积累的目的,其实没什么难度,但是一件很琐碎的事情真的也需要时间去完成和调试,所以,获取你在写一个功能的时候会觉得并没有多难,但是如果可以最好把代码整理/积累下来. demo描述 demo的功能其实就是仿照微信的 聊天 emoje 选择,采用了 viewpager+gridView 的方案,不过有空我会补上 recyclerView 的方案,目前还是先把功能实现了再说.另外在 TextView 和 EditT

  • Android开发技巧之像QQ一样输入文字和表情图像

    EditText和TextView一样,也可以进行图文混排.所不同的是,TextView只用于显示图文混排效果,而EditText不仅可显示,也可混合输入文字和图像,让我们先回顾一下图5.2所示的QQ聊天输入框,在输入框中可以同时输入文字和表情图像.实际上,这种效果在Android SDK中只需要几行代码就可以实现.为了使读者更有学习的冲动,先来欣赏一下即将实现的效果,如图5.16所示. 图5.16 在EditText控件中输入文字和图像 为了实现这个程序,首先来准备一些要用到的素材,也就是要在

  • Android高仿微信表情输入与键盘输入详解

    最近公司在项目上要使用到表情与键盘的切换输入,自己实现了一个,还是存在些缺陷,比如说键盘与表情切换时出现跳闪问题,这个相当困扰我,不过所幸在Github(其中一个不错的开源项目,其代码整体结构很不错)并且在论坛上找些解决方案,再加上我也是研究了好多个开源项目的代码,最后才苦逼地整合出比较不错的实现效果,可以说跟微信基本一样(嘿嘿,只能说目前还没发现大Bug,若发现大家一起日后慢慢完善,这里我也只是给出了实现方案,拓展其他表情我并没有实现哈,不过代码中我实现了一个可拓展的fragment模板以便大

  • Android编程开发之EditText实现输入QQ表情图像的方法

    本文实例讲述了Android编程开发之EditText实现输入QQ表情图像的方法.分享给大家供大家参考,具体如下: 实现效果如下: 将QQ表情图像放到res下的drawable-hdpi文件夹下: 布局文件: <EditText android:id="@+id/edittext" android:layout_width="fill_parent" android:layout_height="wrap_content" android:

  • Android输入法与表情面板切换时的界面抖动问题解决方法

    昨天琢磨了下Android的输入法弹出模式,突然发现利用动态切换输入法的弹出模式可以解决输入法抖动的问题.具体是怎样的抖动呢?我们先看微博的反面教材. [具体表现为:表情面板与输入法面板高度不一致,从而导致弹出输入法(layout被挤压)时,同时又需要隐藏表情面板(layout被拉升),最终让界面产生了高度差抖动,所以在切换时明显会有不大好的抖动体验)] 使用了解决抖动的解决方案后,效果如下: [这样的方案明显比微博的切换更平滑] 老样子,先说思路.主要我们要用到两个输入法弹出模式,分别是:ad

  • Android自带emoji表情的使用方法详解

    什么是emoji表情 emoji表情是一种表情符号,在代码中它现在其实是一组遵循Unicode的编码,即每一个表情符号都对应了一个Unicode编码.更进一步说,emoji表情实际上是一组Unicode编码与一组表情描述之间的对应.注意,这里所说的不是表情图片,而是表情描述.那么图片的实现是由谁来负责的呢?图片是由各个系统或者软件针对统一的表情描述来各自实现的,他们都遵循统一的Unicode编码规范.也就是说Unicode编码其所对应的表情描述是统一的,是所有人都要共同遵守的一套标准或者规范,而

随机推荐