Android开发中经常用到评论.回复.和发送聊天信息的功能开发,这其中就有表情的插入发送功能,经过长时间的开发总结,先封装出插入表情的功能实现代码开源给大家,共大家参考,共同学习进步:
1.拷贝表情图片资源到drawable其中的文件下,如图:
2.编辑表情对应的文字(自定义名字,叫什么都可以),封装成arrays.xml文件,:
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android" xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string-array name="default_smiley_texts">
<item>"[狗宝宝]"</item>
<item>"[狗生日]"</item>
<item>"[狗吃饭]"</item>
<item>"[狗打针]"</item>
<item>"[狗吠叫]"</item>
<item>"[狗感冒]"</item>
<item>"[狗怀孕]"</item>
<item>"[狗满月]"</item>
<item>"[狗牵手]"</item>
<item>"[狗散步]"</item>
<item>"[狗睡觉]"</item>
<item>"[狗洗澡]"</item>
<item>"[狗摇尾]"</item>
<item>"[狗造型]"</item>
<item>"[猫宝宝]"</item>
<item>"[猫生日]"</item>
<item>"[猫铲屎]"</item>
<item>"[猫吃饭]"</item>
<item>"[猫怀孕]"</item>
<item>"[猫满月]"</item>
<item>"[猫魔爪]"</item>
<item>"[猫睡觉]"</item>
<item>"[猫洗脸]"</item>
<item>"[猫洗澡]"</item>
</string-array>
</resources>
3.封装表情和图片对应的类:
package com.pets.face;
import com.pets.activity.R;
/**
* 表情图片和资源对照表
*
* @author 孤狼
* */
public class Expressions {
public static int[] expressionImgs = new int[] {
R.drawable.icon_dog_baobao, R.drawable.icon_dog_birth,
R.drawable.icon_dog_chifan, R.drawable.icon_dog_dazhen,
R.drawable.icon_dog_feijiao, R.drawable.icon_dog_ganmao,
R.drawable.icon_dog_huaiyun, R.drawable.icon_dog_manyue,
R.drawable.icon_dog_qianshou, R.drawable.icon_dog_sanbu,
R.drawable.icon_dog_shuijiao, R.drawable.icon_dog_xizao,
R.drawable.icon_dog_yaowei, R.drawable.icon_dog_zaoxing,
R.drawable.icon_cat_baobao, R.drawable.icon_cat_birth,
R.drawable.icon_cat_chanshi, R.drawable.icon_cat_chifan,
R.drawable.icon_cat_huanyun, R.drawable.icon_cat_manyue,
R.drawable.icon_cat_mozhao, R.drawable.icon_cat_shuijiao,
R.drawable.icon_cat_xilian, R.drawable.icon_cat_xizao };
public static String[] expressionImgNames = new String[] { "[狗宝宝]",
"[狗生日]", "[狗吃饭]", "[狗打针]", "[狗吠叫]", "[狗感冒]", "[狗怀孕]", "[狗满月]",
"[狗牵手]", "[狗散步]", "[狗睡觉]", "[狗洗澡]", "[狗摇尾]", "[狗造型]", "[猫宝宝]",
"[猫生日]", "[猫铲屎]", "[猫吃饭]", "[猫怀孕]", "[猫满月]", "[猫魔爪]", "[猫睡觉]",
"[猫洗脸]", "[猫洗澡]" };
public static String[] replaceStrings(String[] str, String[] str2) {
String newStr[] = new String[str.length - 1];
for (int i = 0; i < str.length; i++) {
newStr[i] = str[i].replace(str[i], str2[i]);
}
return newStr;
}
}
4.构建工具类,使用正则表达式解析图文混排的内容:(容易错的是表情文字的数组长度和表情图片的数组长度不相等)
package com.pets.face;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import com.pets.activity.R;
import android.content.Context;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.style.ImageSpan;
/**
* 正则表达式转换条目中图文混排的工具类
*
* @author孤狼
* @data 2014-12-19
*/
public class SmileyParser {
/*
* 单例模式 1文字资源,图片资源 2.使用正则表达式进行匹配文字 3.把edittext当中整体的内容匹配正则表达式一次
* 4.SpannableStringBuilder 进行替换
*/
private static SmileyParser sInstance;
public static SmileyParser getInstance() {
return sInstance;
}
public static void init(Context context) {
sInstance = new SmileyParser(context);
}
private final Context mContext;
private final String[] arrText;
// 正则表达式
private final Pattern mPattern;
// String 图片字符串 Integer表情
private final HashMap<String, Integer> mSmileyToRes;
// arrays里面的表情内容
public static final int DEFAULT_SMILEY_TEXTS = R.array.default_smiley_texts;
private SmileyParser(Context context) {
mContext = context;
// 获取表情文字资源
arrText = mContext.getResources().getStringArray(DEFAULT_SMILEY_TEXTS);
// 获取表情ID与表情图标的Map
mSmileyToRes = buildSmileyToRes();
// 获取构建的正则表达式
mPattern = buildPattern();
}
// 表情图片集合
private static final int[] DEFAULT_SMILEY_RES_IDS = {
R.drawable.icon_dog_baobao, R.drawable.icon_dog_birth,
R.drawable.icon_dog_chifan, R.drawable.icon_dog_dazhen,
R.drawable.icon_dog_feijiao, R.drawable.icon_dog_ganmao,
R.drawable.icon_dog_huaiyun, R.drawable.icon_dog_manyue,
R.drawable.icon_dog_qianshou, R.drawable.icon_dog_sanbu,
R.drawable.icon_dog_shuijiao, R.drawable.icon_dog_xizao,
R.drawable.icon_dog_yaowei, R.drawable.icon_dog_zaoxing,
R.drawable.icon_cat_baobao, R.drawable.icon_cat_birth,
R.drawable.icon_cat_chanshi, R.drawable.icon_cat_chifan,
R.drawable.icon_cat_huanyun, R.drawable.icon_cat_manyue,
R.drawable.icon_cat_mozhao, R.drawable.icon_cat_shuijiao,
R.drawable.icon_cat_xilian, R.drawable.icon_cat_xizao };
/**
* 使用HashMap的key-value的形式来影射表情的ID和图片资源
*
* @return
*/
private HashMap<String, Integer> buildSmileyToRes() {
if (DEFAULT_SMILEY_RES_IDS.length != arrText.length) {
throw new IllegalStateException("ID和图片不匹配");
}
HashMap<String, Integer> smileyToRes = new HashMap<String, Integer>(
arrText.length);
for (int i = 0; i < arrText.length; i++) {
// 图片名称作为key值,图片资源ID作为value值
smileyToRes.put(arrText[i], DEFAULT_SMILEY_RES_IDS[i]);
}
return smileyToRes;
}
/**
* 构建正则表达式,用来找到我们所要使用的图片
*
* @return
*/
private Pattern buildPattern() {
StringBuilder patternString = new StringBuilder(arrText.length * 3);
patternString.append('(');
for (String s : arrText) {
patternString.append(Pattern.quote(s));
patternString.append('|');
}
patternString.replace(patternString.length() - 1,
patternString.length(), ")");
// 把String字符串编译成正则表达式()
// ([调皮]|[调皮]|[调皮])
return Pattern.compile(patternString.toString());
}
/**
* 根据文本替换成图片
*
* @param text
* 对应表情
* @return 一个表示图片的序列
*/
public CharSequence addSmileySpans(CharSequence text) {
// 把文字替换为对应图片
SpannableStringBuilder builder = new SpannableStringBuilder(text);
// 判断提取工具类(按照正则表达式)
Matcher matcher = mPattern.matcher(text);
while (matcher.find()) {
// 获取对应表情的图片id
int resId = mSmileyToRes.get(matcher.group());
// 替换制定字符
builder.setSpan(new ImageSpan(mContext, resId), matcher.start(),
matcher.end(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
}
return builder;
}
}
5.提供装载表情的控件,填充表情(要封装起来直接调用就行):
package com.pets.face;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.pets.activity.R;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.ImageSpan;
import android.view.View;
import android.widget.AdapterView;
import android.widget.GridView;
import android.widget.SimpleAdapter;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.TextView;
/**
* 填充装载表情的控件
*
* @author孤狼
* @since 2014-12-12
* */
public class SmileyGrid {
public static void initSimleGrid(final Activity activity,
final int[] expressionImages1,
final String[] expressionImageNames1, GridView gridView,
final TextView content_et) {
List<Map<String, Object>> listItems = new ArrayList<Map<String, Object>>();
// 生成24个表情
for (int i = 0; i < 24; i++) {
Map<String, Object> listItem = new HashMap<String, Object>();
listItem.put("image", expressionImages1[i]);
listItems.add(listItem);
}
SimpleAdapter simpleAdapter = new SimpleAdapter(activity, listItems,
R.layout.singleexpression, new String[] { "image" },
new int[] { R.id.image });
gridView.setAdapter(simpleAdapter);
gridView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
Bitmap bitmap = null;
bitmap = BitmapFactory.decodeResource(activity.getResources(),
expressionImages1[arg2 % expressionImages1.length]);
int width = bitmap.getWidth();
int height = bitmap.getHeight();
Matrix matrix = new Matrix();
// 缩放图片动作
matrix.postScale(0.45f, 0.45f);
Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, width,
height, matrix, true);
ImageSpan imageSpan = new ImageSpan(activity, resizedBitmap);
SpannableString spannableString = new SpannableString(
expressionImageNames1[arg2].substring(0,
expressionImageNames1[arg2].length()));
spannableString.setSpan(imageSpan, 0,
expressionImageNames1[arg2].length(),
Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
// 编辑框设置数据
content_et.append(spannableString);
}
});
}
}
6.使用封装:
package com.pets.face;
import java.util.ArrayList;
import android.app.Activity;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.LayoutInflater;
import android.widget.GridView;
import android.widget.TextView;
import com.pets.activity.R;
import com.pets.customadapter.AdapterUtil;
/**
* 表情显示
* */
public class ShowFaceUtil {
public static void showFace(final Activity activity, ViewPager viewPager,
final TextView content_et) {
// 引入表情
final int[] expressionImages = Expressions.expressionImgs;
final String[] expressionImageNames = Expressions.expressionImgNames;
// 表情ViewPager
LayoutInflater inflater = LayoutInflater.from(activity);
ArrayList<GridView> grids = new ArrayList<GridView>();
GridView gView1 = (GridView) inflater.inflate(R.layout.grid1, null);
grids.add((GridView) gView1);
SmileyGrid.initSimleGrid(activity, expressionImages,
expressionImageNames, gView1, content_et);
viewPager.setAdapter(AdapterUtil.getGridPager(grids));
}
}
7.在Activity中直接调用ShowFaceUtil 的showFace()方法即可,传入ViewPager(大量的图片需要GridView滑动),TextView
好了,表情所需工具类全部封装完成,当调用ShowFaceUtil 的showFace()方法表情就会显示出来,那么从服务器获取的数据中含有表情,如何解析显示在界面上呢?细心的你会发现我们封装的SmileyParser 类中有个方法就是解析替换为表情图片的方法:
初始化// 设置详情,解析表情
SmileyParser.init(activity);
SmileyParser parser = SmileyParser.getInstance();
tv.setText(parser.addSmileySpans(item.getTi_details()));
就是SmileyParser的addSmileySpans(String string)方法
好了,全部完成,本文中的表情图片较少,详细更多的请看我的eoe论坛帖子
自定义表情