关于EditText屏蔽Emoji表情及屏蔽其它非法字符带来的光标不准确问题


最近的项目使用了EditText编辑文本,但需要屏蔽Emoji表情,于是在EditText的addTextChangedListener做了以下操作

    private String before = "";
    int couIndex;
    boolean isAutoSet;

   mTxtReplay.addTextChangedListener(new TextWatcher() {
            @Override
            public void onTextChanged(CharSequence s, int start, int before,
                                      int count) {
                if (!isAutoSet) {//判断是手动编辑录入还是通过setText自动设置的  如果是setText设置,则start为0,不再改变光标位置
                    couIndex = start;//记录最后一次光标所在位置
                }
            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count,
                                          int after) {
                before = s.toString();
            }

            @Override
            public void afterTextChanged(Editable s) {

                if (isEmoji(mTxtReplay.getText().toString()) || mTxtReplay.getText().toString().contains("☺")) {//判断Emoje表情
                    isAutoSet = true;
                    mTxtReplay.setText(before); //setText的时候会调用onTextChanged并重置start位置为0,所以需要
                    isAutoSet = false;
                    mTxtReplay.setSelection(couIndex);//将最后一次输入文本的开始位置再设置到光标位置
                }
                if (mTxtReplay.getText().toString().length() > 1000) {
                    mTxtReplay.setText(before);
                    ToastUtil.showToast(CarOwnerQuestionReplayActivity.this, "最多输入1000字");
                }

            }
        });

/**
     * 判断方便是否是Emoji表情
     * @param string
     * @return
     */
    public boolean isEmoji(String string) {
        Pattern p = Pattern.compile("[\ud83c\udc00-\ud83c\udfff]|[\ud83d\udc00-\ud83d\udfff]|[\u2600-\u27ff]",
                Pattern.UNICODE_CASE | Pattern.CASE_INSENSITIVE);
        Matcher m = p.matcher(string);
        return m.find();
    }










要实现EditText限制长度为10,同时允许输入Emoji表情包,并且避免表情包出现乱码,可以使用自定义的InputFilter来实现。具体步骤如下: 1. 定义一个EmojiInputFilter类,继承InputFilter接口。 2. 在EmojiInputFilter中实现filter()方法,实现限制长度和过滤Emoji表情包的逻辑,具体实现如下: ``` public class EmojiInputFilter implements InputFilter { private static final int MAX_LENGTH = 10; @Override public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { int keep = MAX_LENGTH - (dest.length() - (dend - dstart)); if (keep <= 0) { return ""; } else if (keep >= end - start) { // 如果输入的字符数小于等于限制的长度,则不需要过滤表情包 return null; } else { // 如果输入的字符数大于限制的长度,则需要过滤表情包 int k = start; int len = 0; StringBuilder sb = new StringBuilder(); for (; k < end; k++) { int codePoint = source.charAt(k); if (!Character.isHighSurrogate(codePoint) && !Character.isLowSurrogate(codePoint) && len < keep) { len++; sb.append(Character.toChars(codePoint)); } else { break; } } return sb.toString(); } } } ``` 3. 在EditText中设置输入类型为文本类型,同时添加自定义的EmojiInputFilter,实现限制长度和过滤Emoji表情包的逻辑,具体代码如下: ``` // 设置EditText输入类型为文本类型 editText.setInputType(InputType.TYPE_CLASS_TEXT); // 添加自定义的EmojiInputFilter,实现限制长度和过滤Emoji表情包的逻辑 editText.setFilters(new InputFilter[] {new EmojiInputFilter()}); ``` 4. 在显示输入框中的内容时,通过EmojiCompat工具类将Unicode编码转换成对应的Emoji表情,具体代码如下: ``` // 初始化EmojiCompat EmojiCompat.Config config = new BundledEmojiCompatConfig(context); EmojiCompat.init(config); // 在显示输入框中的内容时,将Unicode编码转换成对应的Emoji表情 CharSequence processed = EmojiCompat.get().process(text); textView.setText(processed); ``` 这样就可以实现EditText限制长度为10,同时允许输入Emoji表情包,并且避免表情包出现乱码了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值