Android限定Editext輸入框字符數(shù)

說明

自定義Editext文本監(jiān)聽textWatcher,限制字符數(shù)量

  • String.length()誤區(qū)
  • byte編碼不同,漢字和字母的比率也不同
  • 不同字符長度如何區(qū)分截取
  • 光標(biāo)的處理

String.length()誤區(qū)

因為我們是監(jiān)聽Editext字符數(shù)量,那么問題來了,String.length()方法能否直接判斷長度,答案是否定的,我們的輸入框既可以輸入漢字,也可以輸入英文字母,或者也可以輸入數(shù)字,他們在不同的字節(jié)編碼下,對應(yīng)的長度關(guān)系也截然不同,所以只能采取byte數(shù)組來判斷

不同字符集編碼,對應(yīng)的長度關(guān)系

英文字母:
字節(jié)數(shù) : 1;編碼:GB2312
字節(jié)數(shù) : 1;編碼:GBK
字節(jié)數(shù) : 1;編碼:GB18030
字節(jié)數(shù) : 1;編碼:ISO-8859-1
字節(jié)數(shù) : 1;編碼:UTF-8
字節(jié)數(shù) : 4;編碼:UTF-16
字節(jié)數(shù) : 2;編碼:UTF-16BE
字節(jié)數(shù) : 2;編碼:UTF-16LE

中文漢字:
字節(jié)數(shù) : 2;編碼:GB2312
字節(jié)數(shù) : 2;編碼:GBK
字節(jié)數(shù) : 2;編碼:GB18030
字節(jié)數(shù) : 1;編碼:ISO-8859-1
字節(jié)數(shù) : 3;編碼:UTF-8
字節(jié)數(shù) : 4;編碼:UTF-16
字節(jié)數(shù) : 2;編碼:UTF-16BE
字節(jié)數(shù) : 2;編碼:UTF-16LE

不同的字符長度如何截取

比如,我們的限定字符長度為20,現(xiàn)在已經(jīng)輸入了19個字符,如果在輸入兩個字母,那么就變成21個字符,直接截取掉最后一個即可,但是如果此時輸入一個漢字,如何截取,一個漢字占用2個字符,總不能把漢字截去一半吧,那么有可能出現(xiàn)亂碼,此時直接舍去漢字。

光標(biāo)的處理

監(jiān)聽文本光標(biāo)一定要放到后面,不然也會有各種問題

代碼

public class CustomWatcherText implements TextWatcher {
    private int maxLen = 10; //默認(rèn)長度為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();
                // 舊光標(biāo)位置超過字符串長度
                if (selEndIndex >= newLen) {
                    selEndIndex = editable.length();
                }
                //設(shè)置新光標(biāo)所在的位置
                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監(jiān)聽的地方使用:
 editext.addTextChangedListener(new CustomWatcherText(context, 20, editext));

非常感謝你的瀏覽!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 《ilua》速成開發(fā)手冊3.0 官方用戶交流:iApp開發(fā)交流(1) 239547050iApp開發(fā)交流(2) 1...
    葉染柒丶閱讀 11,519評論 0 11
  • 《ijs》速成開發(fā)手冊3.0 官方用戶交流:iApp開發(fā)交流(1) 239547050iApp開發(fā)交流(2) 10...
    葉染柒丶閱讀 5,647評論 0 7
  • 最初吃素源于一個信佛的朋友指引,說是吃素念佛可以為病人祈福!當(dāng)時抱著試試的心態(tài)就照做了,時至17年1月10號,忘...
    毅往直前閱讀 1,621評論 0 1
  • 夏天就是用來感受清爽的,感恩它們在炎熱中帶來的美好。 (一)綠 生命的昂揚(yáng),青春的旺盛,寂靜地招搖。 (二...
    風(fēng)飲雨閱讀 276評論 0 0
  • 二維碼SDK的Dome“QRCode”中制作libqrencode庫文件,掃描ZBarSDK庫文件 1.制作二維碼...
    wuli炫邁君ker閱讀 486評論 0 0

友情鏈接更多精彩內(nèi)容