Android限定Editext输入框字符数

说明

自定义Editext文本监听textWatcher,限制字符数量

  • String.length()误区
  • byte编码不同,汉字和字母的比率也不同
  • 不同字符长度如何区分截取
  • 光标的处理

String.length()误区

因为我们是监听Editext字符数量,那么问题来了,String.length()方法能否直接判断长度,答案是否定的,我们的输入框既可以输入汉字,也可以输入英文字母,或者也可以输入数字,他们在不同的字节编码下,对应的长度关系也截然不同,所以只能采取byte数组来判断

不同字符集编码,对应的长度关系

英文字母:
字节数 : 1;编码:GB2312
字节数 : 1;编码:GBK
字节数 : 1;编码:GB18030
字节数 : 1;编码:ISO-8859-1
字节数 : 1;编码:UTF-8
字节数 : 4;编码:UTF-16
字节数 : 2;编码:UTF-16BE
字节数 : 2;编码:UTF-16LE

中文汉字:
字节数 : 2;编码:GB2312
字节数 : 2;编码:GBK
字节数 : 2;编码:GB18030
字节数 : 1;编码:ISO-8859-1
字节数 : 3;编码:UTF-8
字节数 : 4;编码:UTF-16
字节数 : 2;编码:UTF-16BE
字节数 : 2;编码:UTF-16LE

不同的字符长度如何截取

比如,我们的限定字符长度为20,现在已经输入了19个字符,如果在输入两个字母,那么就变成21个字符,直接截取掉最后一个即可,但是如果此时输入一个汉字,如何截取,一个汉字占用2个字符,总不能把汉字截去一半吧,那么有可能出现乱码,此时直接舍去汉字。

光标的处理

监听文本光标一定要放到后面,不然也会有各种问题

代码

public class CustomWatcherText implements TextWatcher {
    private int maxLen = 10; //默认长度为10个字符
    private EditText editText = null;
    private Context context;

    public CustomWatcherText(Context context, int maxLen, EditText editText) {
        this.maxLen = maxLen;
        this.editText = editText;
        this.context = context;
    }

    public void afterTextChanged(Editable arg0) {
        // TODO Auto-generated method stub

    }

    public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
                                  int arg3) {
        // TODO Auto-generated method stub

    }

    public void onTextChanged(CharSequence arg0, int arg1, int arg2, int arg3) {
        try {
            // TODO Auto-generated method stub
            Editable editable = editText.getText();
            String content = editText.getText().toString();
            byte[] bt = content.getBytes("gb2312");
            if (bt.length > maxLen) {
                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 = isContainChinese(temp);
                boolean flag2 = isContainLetters(temp);
                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);
                Toast.makeText(context,"超出"+maxLen/2+"个汉字",Toast.LENGTH_SHORT).show();
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

    private byte[] subBytes(byte[] src, int begin, int count) {
        byte[] bs = new byte[count];
        System.arraycopy(src, begin, bs, 0, count);
        return bs;
    }

    private String gbToString(byte[] data) {
        String str = null;
        try {
            str = new String(data, "gb2312");
        } catch (UnsupportedEncodingException e) {
        }
        return str;
    }

    /**
     * 判断字符串是否包含字母
     * @param str
     * @return
     */
    public boolean isContainLetters(String str) {
        for (char i = 'A'; i <= 'Z'; i++) {
            if (str.contains(String.valueOf(i))) {
                return true;
            }
        }
        for (char i = 'a'; i <= 'z'; i++) {
            if (str.contains(String.valueOf(i))) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断字符串是否包含中文
     * @param str
     * @return
     */
    public boolean isContainChinese(String str) {
        Pattern p = Pattern.compile("[\u4e00-\u9fa5]");
        Matcher m = p.matcher(str);
        return m.find();
    }
}
在Editext监听的地方使用:
 editext.addTextChangedListener(new CustomWatcherText(context, 20, editext));

非常感谢你的浏览!

你可能感兴趣的:(Android限定Editext输入框字符数)