天天看點

Android的EditText字數檢測和限制

控件EditText在android布局中經常用到,對EditText中輸入的内容也經常需要進行限制,我們可以通過TextWatcher去觀察輸入框中輸入的内容。

public class TextWatcherDemo extends Activity {
    private TextView mTextView;
    private EditText mEditText;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mTextView = (TextView)findViewById(R.id.tv);
        mEditText = (EditText)findViewById(R.id.ET);
        mEditText.addTextChangedListener(mTextWatcher);
    }

    TextWatcher mTextWatcher = new TextWatcher() {
        private CharSequence temp;
        private int editStart ;
        private int editEnd ;
        @Override
        public void beforeTextChanged(CharSequence s, int arg1, int arg2, int arg3) {
            temp = s;
        }

        @Override
        public void onTextChanged(CharSequence s, int arg1, int arg2,int arg3) {
            mTextView.setText(s);
        }

       
        @Override

        public void afterTextChanged(Editable s) {
            editStart = mEditText.getSelectionStart();
            editEnd = mEditText.getSelectionEnd();
            if (temp.length() > 10) {
                Toast.makeText(TextWatcherDemo.this,
                        "你輸入的字數已經超過了限制!", Toast.LENGTH_SHORT).show();
                s.delete(editStart-1, editEnd);
                int tempSelection = editStart;
                mEditText.setText(s);
                mEditText.setSelection(tempSelection);
            }
        }
    };
}      

關于android中的編碼

result.getBytes() 是 new String(byte[]) 的逆過程。

前面那個是 String->byte[] ,後面那個是 byte[] -> String.

在java運作時的時候,String與String是沒有差別的都是以2位元組的unicode的形式存在記憶體中,所謂編碼,是針對把String轉換成 byte[]而言的。比如我可以把 “abc” 通過 utf-8轉換成了一串資料 A ,也可以通過gb2312轉換成另一串資料 B,這個過程就是 String.getBytes(),比如 “abc”.getBytes(“utf-8”)得到A , “abc”.getBytes(“gb2312”)得到B。如果是"abc".getBytes(),就不知道用的什麼編碼了,這和平台相關。

那如何從A串或者 B串重新得到String呢,那就是 new String(A,“utf-8”) 或者 new String(B,“gb2312”)。因為A是從utf-8轉換得到的,是以用utf-8轉回String ,如果new String(A,“gb2312”), 那麼其中的中文就是亂碼。

下面列出各編碼格式下字元的位元組數:

英文字母:A

位元組數: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

根據上面的結果,我們可以通過每個字元的UTF-8位元組數來判斷是中文還是英文。

工作中遇到一個需求,是要限制EditText中輸入的字元數的個數,中文15個,英文30個,中英文會交叉輸入,就可以用上面的條件來判斷。

private TextWatcher mInputTextWatcher = new TextWatcher() {
        private String temp;
        private int editStart;
        private int editEnd;
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            temp = s.toString();
        }
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        }
        @Override
        public void afterTextChanged(Editable s) {
mMainHandler.removeMessages(HD_MSG_UPDATE_HINT);
            mCurrentHint = s.toString().trim();
            if (!TextUtils.isEmpty(temp)) {
                String limitSubstring = getLimitSubstring(temp);
                if (!TextUtils.isEmpty(limitSubstring)) {
                    if (!limitSubstring.equals(temp)) {
                        // Toast.makeText(activity, "字數已超過限制",
                        // Toast.LENGTH_SHORT).show();
                        mEdtInput.setText(limitSubstring);
                        mEdtInput.setSelection(limitSubstring.length());
                    }
                }
            }
       mMainHandler.sendEmptyMessageDelayed(HD_MSG_UPDATE_HINT, HINT_UPDATE_DALEY_TIME);
        }
    };

    private String getLimitSubstring(String inputStr) {
        int orignLen = inputStr.length();
        int resultLen = 0;
        String temp = null;
        for (int i = 0; i < orignLen; i++) {
            temp = inputStr.substring(i, i + 1);
            try {// 3 bytes to indicate chinese word,1 byte to indicate english
                 // word ,in utf-8 encode
                if (temp.getBytes("utf-8").length == 3) {
                    resultLen += 2;
                } else {
                    resultLen++;
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            if (resultLen > 30) {
                return inputStr.substring(0, i);
            }
        }
        return inputStr;
    }