使用表情过滤工具在魅族手机和华为手机上会报错的问题

前言:最后客户反馈过来一个问题说是在华为mate7 和 魅族手机上出现在26键编辑模式下程序会崩溃,我在公司用的是小米的测试机,所有就从来都没有遇到这样的情况.我的小米的手机的输入情况如下图,这样的情况是不会报错的.但是华为的手机和魅族的手机会在输入框中也显示你正在输入的内容就导致我在使用表情过滤的监听里面会出现获取到的字符串的数量出现偏差.

这里写图片描述

我的表情过滤工具类是这样写的

/**
 * 输入帮助类
 */
public class EditTextHelper {

    /**
     * 设置EditText内容并移动光标到尾部
     *
     * @param edittext
     * @param text
     */
    public static void setTextAndSelectEnd(EditText edittext, CharSequence text) {
        edittext.setText(text);
        edittext.setSelection(edittext.getText().length());
    }

    public static void addEmojiFilter(final EditText edittext) {
        edittext.addTextChangedListener(new TextWatcher() {
            // 是否重置了EditText的内容
            private boolean resetText;
            private int cursorPos;
            // 输入表情前EditText中的文本
            private String inputAfterText;

            @Override
            public void beforeTextChanged(CharSequence s, int start,
                                          int before, int count) {
                if (!resetText) {
                    cursorPos = edittext.getSelectionEnd();
                    // 这里用s.toString()而不直接用s是因为如果用s,
                    // 那么,inputAfterText和s在内存中指向的是同一个地址,s改变了,
                    // inputAfterText也就改变了,那么表情过滤就失败了
                    inputAfterText = s.toString();
                }

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before,
                                      int count) {
                if (!resetText) {
                    if (count >= 2) {// 表情符号的字符长度最小为2
                         //如果这里不加这样的判断就会应该刚刚之前的操作报下标越界的错误
//                        if (cursorPos + count > s.length()) {
//                            return;
//                        }
                        CharSequence input = s.subSequence(cursorPos, cursorPos + count);
                        if (containsEmoji(input.toString())) {
                            resetText = true;
                            // Toast.makeText(mContext, "不支持输入Emoji表情符号",
                            // Toast.LENGTH_SHORT).show();
                            // 是表情符号就将文本还原为输入表情符号之前的内容
                            inputAfterText += filterEmoji(input.toString());
                            edittext.setText(inputAfterText);
                            CharSequence text = edittext.getText();
                            if (text instanceof Spannable) {
                                Spannable spanText = (Spannable) text;
                                Selection.setSelection(spanText, text.length());
                            }
                        }
                    }
                } else {
                    resetText = false;
                }
            }

            @Override
            public void afterTextChanged(Editable editable) {

            }
        });
    }

    /**
     * 检测是否有emoji表情
     *
     * @param source
     * @return
     */
    public static boolean containsEmoji(String source) {
        int len = source.length();
        for (int i = 0; i < len; i++) {
            char codePoint = source.charAt(i);
            if (!isEmojiCharacter(codePoint)) { // 如果不能匹配,则该字符是Emoji表情
                return true;
            }
        }
        return false;
    }

    /**
     * 过滤emoji表情
     *
     * @param source
     * @return
     */
    public static String filterEmoji(String source) {
        StringBuilder sb = new StringBuilder();
        int len = source.length();
        for (int i = 0; i < len; i++) {
            char codePoint = source.charAt(i);
            if (isEmojiCharacter(codePoint)) { // 如果不能匹配,则该字符是Emoji表情
                // return true;
                sb.append(codePoint);
            }
        }
        return sb.toString();
    }

    /**
     * 判断是否是Emoji
     *
     * @param codePoint 比较的单个字符
     * @return
     */
    private static boolean isEmojiCharacter(char codePoint) {
        return (codePoint == 0x0) || (codePoint == 0x9) || (codePoint == 0xA)
                || (codePoint == 0xD)
                || ((codePoint >= 0x20) && (codePoint <= 0xD7FF))
                || ((codePoint >= 0xE000) && (codePoint <= 0xFFFD))
                || ((codePoint >= 0x10000) && (codePoint <= 0x10FFFF));
    }


    /**
     * 银行卡四位加空格
     *
     * @param mEditText
     */
    public static void bankCardNumAddSpace(final EditText mEditText) {
        mEditText.addTextChangedListener(new TextWatcher() {
            int beforeTextLength = 0;
            int onTextLength = 0;
            boolean isChanged = false;

            int location = 0;// 记录光标的位置
            private char[] tempChar;
            private StringBuffer buffer = new StringBuffer();
            int konggeNumberB = 0;

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count,
                                          int after) {
                beforeTextLength = s.length();
                if (buffer.length() > 0) {
                    buffer.delete(0, buffer.length());
                }
                konggeNumberB = 0;
                for (int i = 0; i < s.length(); i++) {
                    if (s.charAt(i) == ' ') {
                        konggeNumberB++;
                    }
                }
            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before,
                                      int count) {
                onTextLength = s.length();
                buffer.append(s.toString());
                if (onTextLength == beforeTextLength || onTextLength <= 3
                        || isChanged) {
                    isChanged = false;
                    return;
                }
                isChanged = true;
            }

            @Override
            public void afterTextChanged(Editable s) {
                if (isChanged) {
                    location = mEditText.getSelectionEnd();
                    int index = 0;
                    while (index < buffer.length()) {
                        if (buffer.charAt(index) == ' ') {
                            buffer.deleteCharAt(index);
                        } else {
                            index++;
                        }
                    }

                    index = 0;
                    int konggeNumberC = 0;
                    while (index < buffer.length()) {
                        if ((index == 4 || index == 9 || index == 14 || index == 19)) {
                            buffer.insert(index, ' ');
                            konggeNumberC++;
                        }
                        index++;
                    }

                    if (konggeNumberC > konggeNumberB) {
                        location += (konggeNumberC - konggeNumberB);
                    }

                    tempChar = new char[buffer.length()];
                    buffer.getChars(0, buffer.length(), tempChar, 0);
                    String str = buffer.toString();
                    if (location > str.length()) {
                        location = str.length();
                    } else if (location < 0) {
                        location = 0;
                    }
                    mEditText.setText(str);
                    Editable etable = mEditText.getText();
                    Selection.setSelection(etable, location);
                    isChanged = false;
                }
            }
        });
    }

    /**
     * 输入框字数显示
     * @param editText 输入框
     * @param tvShow  字数显示控件
     * @param maxNumber 最大值
     */
    public static void editContentNumber(final EditText editText,final TextView tvShow,final int maxNumber){
//        editText. setFilters(new InputFilter[] { new InputFilter.LengthFilter(maxNumber) });
        editText.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                tvShow.setText(String.format("%d/%d",editText.getText().length(),maxNumber));
            }

            @Override
            public void afterTextChanged(Editable s) {

            }
        });
    }
}

*加一层这样的判断,就可以避免这种现象发生

            if (cursorPos + count > s.length()) {
                            return;
                        }
  • 另外如果公司如果有需要过滤到表情的话,这个工具类挺好用的,只需要再activity或者是fragment的oncreat方法里面 初始化一次就可以了 例如
     EditTextHelper.addEmojiFilter(editext);//过滤掉表情  不让用户输入表情
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值