Implementation of Android custom emoticon function

Comments, replies, and functions for sending chat messages are often used in Android development. Among them, there is the function of inserting and sending expressions. After a long period of development and summarization, we will first encapsulate the function of inserting expressions and open source the code to everyone. For reference, learn and progress together:
1. Copy the emoji image resource to the file in the drawable, as shown in the figure:
Emoji image resources
2. Edit the text corresponding to the emoji (custom name, whatever you want), package it into an arrays.xml file,:

<?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. Encapsulate the classes corresponding to expressions and pictures:

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. Build a tool class and use regular expressions to parse the content of mixed images and texts: (It is easy to make mistakes because the array length of emoji text and the array length of emoji pictures are not equal)

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. Provide controls for loading expressions and fill in expressions (just call them directly if you want to encapsulate them):

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. Use package:

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. Call the showFace() method of ShowFaceUtil directly in the Activity, pass in the ViewPager (a large number of pictures require GridView sliding), the TextView
is ready, all the tools required for the expression are encapsulated, and when the showFace() method of ShowFaceUtil is called, the expression It will be displayed, then the data obtained from the server contains expressions, how to parse and display it on the interface? If you are careful, you will find that there is a method in the SmileyParser class that we encapsulated, which is to parse and replace the method with the expression picture:

初始化// 设置详情,解析表情
 SmileyParser.init(activity);
 SmileyParser parser = SmileyParser.getInstance();
tv.setText(parser.addSmileySpans(item.getTi_details()));
就是SmileyParser的addSmileySpans(String string)方法

Ok, all done, there are fewer emoji pictures in this article, for more details, please see my eoe forum post
Custom emoji

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325408959&siteId=291194637