输入框的输入字符(字节)监听控制,及实时限制输入规则

* 描述:监听输入框输入的字符数
* 要注意:
* 1、一个汉字算2个字符;
* 2、截取显示输入内容后注意光标位置;
* 3、如还能再输入一个字符,如果数的是汉字,要加以处理,以及光标重定位问题

在android 开发中,经常会遇到要求输入框内输入的文本内容限制10个汉字或20个字母的要求。之前也在网上看了很多解决方案,效果都不是很好,大多数都是直接取字符串的length()作为限定的判断依据,这个思路是非常不对的,单纯的用String.length(),去判断字符串的长度,字母和汉字的长度一样,因此我们要换一个思路去想。

根据“10个汉字或20个字母的要求”,我们可以看出,这里的汉字和字母的长度关系比值是1:2的关系,因此我们要对字符串进行编码,这个编码就是要实现这个汉字和字母1:2的比值关系,这里我们用GB2312编码,不同的编码格式,比值关系不一样,这里大家要注意!!!

public class WatcherTextUtil implements TextWatcher {

    private int maxLen = 0;
    private EditText editText = null;

    //输入筛选条件
    private String regex;

    public WatcherTextUtil(int maxLen, EditText editText) {
        this.maxLen = maxLen;
        this.editText = editText;
    }

    @Override
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

    }

    @Override
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
        try {
            // TODO Auto-generated method stub
            Editable editable = editText.getText();
            String content = editText.getText().toString();

            byte[] bt = content.getBytes("gb2312");
            if (bt.length > maxLen) {
                LogUtils.d("输入字符数超过限制");
                int selEndIndex = Selection.getSelectionEnd(editable);
                String str = editable.toString();
                byte[] bt2 = str.getBytes("gb2312");
                byte[] bt3 = subBytes(bt2, 0, maxLen);
                String newStrs = gbToString(bt3);
                String temp = String.valueOf(newStrs.charAt(newStrs.length() - 1));
                /***对最后一个字符的输入判断(正则表达式可自行修改适配):如果是汉字,将截取的一半数字字符舍去;如果是字母或数字,则保留***/
                boolean flag = Pattern.compile("[\\u4e00-\\u9fa5]").matcher(temp).matches();//汉字
                boolean flag2 = (Pattern.compile("[a-zA-Z]").matcher(temp).matches()) || (Pattern.compile("[0-9]*").matcher(temp).matches());//字母或数字
                if (!flag && !flag2) {
                    String newStrs2 = newStrs.substring(0, newStrs.length() - 1);
                    editText.setText(newStrs2);
                } else {
                    editText.setText(newStrs);
                }
                editable = editText.getText();
                // 新字符串的长度
                int newLen = editable.length();
                // 旧光标位置超过字符串长度
                if (selEndIndex >= newLen) {
                    selEndIndex = editable.length();
                }
                //设置新光标所在的位置
                Selection.setSelection(editable, selEndIndex);

            }

        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void afterTextChanged(Editable editable) {

    }


    /**
     * 将超过的字符串截取,当然,这里一定要先编码后在截取,而且是byte[]数组截取
     */
    private byte[] subBytes(byte[] src, int begin, int count) {
        byte[] bs = new byte[count];
        System.arraycopy(src, begin, bs, 0, count);
        return bs;
    }

    /**
     * 截取好后,当然也要把byte数组里的内容转成字符串形式展现
     *
     */
    private String gbToString(byte[] data) {
        String str = null;
        try {
            str = new String(data, "gb2312");
        } catch (UnsupportedEncodingException e) {
        }
        return str;
    }



}

类中直接使用:

//控制输入的字符总数
mEd_role_id.addTextChangedListener(new WatcherTextUtil(12, mEd_role_id));

2、限制输入框只能输入中文、英文、数字

 mEd_role_id.setFilters(new InputFilter[]{
                new InputFilter() {
                    @Override
                    public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
                        for (int i = start; i < end; i++) {
                            if (!Character.isLetterOrDigit(source.charAt(i))) {
                                return "";
                            }
                        }
                        return null;
                    }
                }
        });

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章