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));

非常感谢你的浏览!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 《ilua》速成开发手册3.0 官方用户交流:iApp开发交流(1) 239547050iApp开发交流(2) 1...
    叶染柒丶阅读 13,800评论 0 11
  • 《ijs》速成开发手册3.0 官方用户交流:iApp开发交流(1) 239547050iApp开发交流(2) 10...
    叶染柒丶阅读 10,822评论 0 7
  • 最初吃素源于一个信佛的朋友指引,说是吃素念佛可以为病人祈福!当时抱着试试的心态就照做了,时至17年1月10号,忘...
    毅往直前阅读 5,328评论 0 1
  • 夏天就是用来感受清爽的,感恩它们在炎热中带来的美好。 (一)绿 生命的昂扬,青春的旺盛,寂静地招摇。 (二...
    风饮雨阅读 1,751评论 0 0
  • 二维码SDK的Dome“QRCode”中制作libqrencode库文件,扫描ZBarSDK库文件 1.制作二维码...
    wuli炫迈君ker阅读 3,161评论 0 0

友情链接更多精彩内容