輸入框的輸入字符(字節)監聽控制,及實時限制輸入規則

* 描述:監聽輸入框輸入的字符數
* 要注意:
* 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;
                    }
                }
        });

 

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