Android表情解决方案

Android涉及消息通讯的时候通常要求支持表情如即时通信,评论回复等,网上有个demo(出处http://download.csdn.net/detail/lnb333666/5288404),

稍作修改,代码如下

表情工具类初始化有点费时,可在子线程进行,不过,放在主线程似乎也没什么大碍。

public class MainActivity extends AppCompatActivity
{

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);



        //        new Thread(new Runnable() {
//            @Override
//            public void run()
//            {
//                //处理表情数据,使之分页封装完毕
//                FaceConversionUtils.getIntance().getFileText(getApplication());
//            }
//        }).start();

        FaceConversionUtils.getIntance().getFileText(getApplication());

        findViewById(R.id.btn_chat).setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                Intent intent = new Intent(MainActivity.this, ChatActivity.class);
                startActivity(intent);
            }
        });
    }
}

  关键工具类

/**
 * 1、解析asset文件,得到一个内容为asset文件一行文字的String集合list,集合实体emoji_1.png,[可爱]
 * 2、封装一个ChatEmoji的bean,内含文件名,描述,对应drawId变量(根据文件名如emoji_1.png),遍历list,填充数据。得到表情集合,集合实体为ChatEmoji
 * 3、将集合实体分页,每一页也是一个集合List<List<ChatEmoji>> emjisLists
 *
 * @see [相关类/方法]
 * @since [产品/模板版本]
 * @deprecated
 */
public class FaceConversionUtils
{
    private static FaceConversionUtils mFaceConversionUtils;

    /**
     * 每一页表情的个数
     */
    private int pagerSize = 20;
    /**
     * 保存于内存中的表情HashMap
     */
    private HashMap<String,String> emojiMap = new HashMap<String,String>();
    /**
     * 保存于内存中的表情集合
     */
    private List<ChatEmoji> emojis = new ArrayList<ChatEmoji>();

    /**
     * 表情分页的结果集合
     */
    public List<List<ChatEmoji>> emjisLists = new ArrayList<List<ChatEmoji>>();

    private ChatEmoji mEmojEntry;
    private Bitmap mBitmap;

    public static FaceConversionUtils getIntance()
    {
        if(mFaceConversionUtils == null)
        {
            mFaceConversionUtils = new FaceConversionUtils();
        }
        return mFaceConversionUtils;


    }

    public void getFileText(Context context)
    {
        ArrayList<String> list = new ArrayList<>();
        try
        {
            InputStream emojiInput = context.getResources().getAssets().open("emoji");
            BufferedReader br = new BufferedReader(new InputStreamReader(emojiInput, "UTF-8"));
            String str = null;
            while(( str = br.readLine() ) != null)
            {
                list.add(str);
            }
        }catch(IOException e)
        {


            e.printStackTrace();
        }
        for(String str : list)
        {
            //emoji_1.png,[可爱]
            String[] text = str.split(",");
            String fileName = text[0].substring(0, text[0].lastIndexOf("."));
            emojiMap.put(text[1], fileName);
            //这行代码是重点!!!
            int drawId = context.getResources().getIdentifier(fileName, "drawable", context.getPackageName());
            if(drawId != 0)
            {
                mEmojEntry = new ChatEmoji();
                mEmojEntry.id = drawId;
                mEmojEntry.character = text[1];
                mEmojEntry.faceName = fileName;
                emojis.add(mEmojEntry);
            }
        }

        int pageCount = (int)Math.ceil(emojis.size()/20+0.1);
        for(int i = 0; i<pageCount; i++)
        {
            emjisLists.add(getData(i));
        }
    }

    private List<ChatEmoji> getData(int pageCount)
    {
        int startIndex = pageCount*pagerSize;
        int endIndex = startIndex+pagerSize;
        //最后一页
        if(endIndex>emojis.size())
        {
            endIndex = emojis.size();
        }
        //        List<ChatEmoji> chatEmojis = emojis.subList(startIndex, endIndex);
        //        return chatEmojis;


        List<ChatEmoji> list = new ArrayList<ChatEmoji>();
        list.addAll(emojis.subList(startIndex, endIndex));
        if(list.size()<pagerSize)
        {
            for(int i = list.size(); i<pagerSize; i++)
            {
                ChatEmoji object = new ChatEmoji();
                list.add(object);
            }
        }
        if(list.size() == pagerSize)
        {
            ChatEmoji object = new ChatEmoji();
            object.id = ( R.drawable.face_del_icon );
            list.add(object);
        }
        return list;
    }


    /**
     * 添加表情
     *
     * @param context
     * @param imgId
     * @param spannableString
     * @return
     */
    public SpannableString addFace(Context context, int imgId,
                                   String spannableString) {
        if (TextUtils.isEmpty(spannableString)) {
            return null;
        }
        Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),
                imgId);
        float density = context.getResources().getDisplayMetrics().density;
        bitmap = Bitmap.createScaledBitmap(bitmap, (int)(20*density), (int)(20*(density)), true);
        ImageSpan imageSpan = new ImageSpan(context, bitmap);
        SpannableString spannable = new SpannableString(spannableString);
        spannable.setSpan(imageSpan, 0, spannableString.length(),
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        return spannable;
    }

    public SpannableString getExpressionString(Context context, String str)
    {
        SpannableString spannableString = new SpannableString(str);
        // 正则表达式比配字符串里是否含有表情,如: 我好[开心]啊
        String zhengze = "\\[[^\\]]+\\]";
        // 通过传入的正则表达式来生成一个pattern
        Pattern sinaPatten = Pattern.compile(zhengze, Pattern.CASE_INSENSITIVE);
        try {
            dealExpression(context, spannableString, sinaPatten, 0);
        } catch (Exception e) {
            Log.e("dealExpression", e.getMessage());
        }
        return spannableString;



    }

    private void dealExpression(Context context, SpannableString spannableString, Pattern patten,int start)
    {
        Matcher matcher = patten.matcher(spannableString);
        while (matcher.find()) {
            String key = matcher.group();
            // 返回第一个字符的索引的文本匹配整个正则表达式,ture 则继续递归
            if (matcher.start() < start) {
                continue;
            }
            String value = emojiMap.get(key);
            if (TextUtils.isEmpty(value)) {
                continue;
            }
            int resId = context.getResources().getIdentifier(value, "drawable",
                    context.getPackageName());
            // 通过上面匹配得到的字符串来生成图片资源id
            // Field field=R.drawable.class.getDeclaredField(value);
            // int resId=Integer.parseInt(field.get(null).toString());
            if (resId != 0) {
                Bitmap bitmap = BitmapFactory.decodeResource(
                        context.getResources(), resId);
                float density = context.getResources().getDisplayMetrics().density;
                bitmap = Bitmap.createScaledBitmap(bitmap, (int)(40*density), (int)(40*density), true);
                // 通过图片资源id来得到bitmap,用一个ImageSpan来包装
                ImageSpan imageSpan = new ImageSpan(bitmap);
                // 计算该图片名字的长度,也就是要替换的字符串的长度
                int end = matcher.start() + key.length();
                // 将该图片替换字符串中规定的位置中
                spannableString.setSpan(imageSpan, matcher.start(), end,
                        Spannable.SPAN_INCLUSIVE_EXCLUSIVE);
                if (end < spannableString.length()) {
                    // 如果整个字符串还未验证完,则继续。。
                    dealExpression(context, spannableString, patten, end);
                }
                break;
            }
        }
    }
}


源码

https://github.com/gangjin1991/ChatDemo


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值