Android 巧用正則表達式+TextWatcher實時限制用戶輸入

一般我們在限制用戶輸入的時候,都是要等到用戶在EditText裏面輸入了文本後,點擊某個按鈕,再去校驗用戶的輸入是否符合規範。

接下來我介紹個新方法,可以在用戶輸入不規範的字符後,還沒在EditText裏顯示出來時,就把用戶的錯誤輸入給忽略掉,不顯示在EditText中,只有當用戶輸入了符合規範的字符時才能在EditText中顯示出來。

這裏需要使用到正則表達式和TextWatcher接口。

對TextWatcher不是很瞭解的同學看我的這篇博客:http://blog.csdn.net/zhuwentao2150/article/details/51546773

主要思路

當用戶輸入時,使用TextWatcher對用戶的輸入進行抓取,在文本還沒有顯示到界面之前,使用正則表達式作爲判定條件,判斷用戶的輸入是否符合標準,不符合則不顯示在EditText中。

具體實現

ExamineTextWatcher實現了TextWatcher接口,在裏面對用戶輸入的字符進行抓取,並調用校驗方法

/**
* 用戶輸入驗證器
* <p/>
* Created by zhuwentao on 2016-08-04.
*/
public class ExamineTextWatcher implements TextWatcher {
    private static final String TAG = "ExamineTextWatcher";

    /**
     * 帳號
     */
    public static final int TYPE_ACCOUNT = 1;

    /**
     * 金額
     */
    public static final int TYPE_MONEY = 2;

    /**
     * 輸入框
     */
    private EditText mEditText;

    /**
     * 驗證類型
     */
    private int examineType;

    /**
     * 輸入前的文本內容
     */
    private String beforeText;

    /**
     * 構造器
     *
     * @param type     驗證類型
     * @param editText 輸入框
     */
    public ExamineTextWatcher(int type, EditText editText) {
        this.examineType = type;
        this.mEditText = editText;
    }

    @Override
    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        // 輸入前的字符
        beforeText = s.toString();
        Log.d(TAG, "beforeText =>>>" + beforeText );
    }

    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count) {
        // 輸入後的字符
        String afterText = s.toString();
        Log.d(TAG, "afterText =>>>" + afterText);

        boolean isValid = true;
        if (!TextUtils.isEmpty(afterText)) {
            switch (examineType) {
                case TYPE_ACCOUNT:
                    isValid = ValidateUtil.isAccount(afterText);
                    break;
                case TYPE_MONEY:
                    isValid = ValidateUtil.isMoney(afterText);
                    break;
            }
            if (!isValid) {
                // 用戶現在輸入的字符數減去之前輸入的字符數,等於新增的字符數
                int differ = afterText.length() - beforeText.length();
                // 如果用戶的輸入不符合規範,則顯示之前輸入的文本
                mEditText.setText(beforeText);
                // 光標移動到文本末尾
                mEditText.setSelection(afterText.length() - differ);
            }
        }
    }

    @Override
    public void afterTextChanged(Editable s) {

    }
}

新建一個工具類ValidateUtil,使用正則表達式對用戶輸入的字符進行匹配

/**
* 驗證工具
*
* Created by zhuwentao on 2016-08-04.
*/
public class ValidateUtil {

    private ValidateUtil() {
        // 防止被實例化
    }

    /**
     * 字符串是否符合正則表達式的規則
     *
     * @param text 匹配文本
     * @param format 匹配規則
     * @return true 匹配成功 flase 匹配失敗
     */
    private static boolean isMatches(String text, String format) {
        Pattern pattern = Pattern.compile(format);
        Matcher m = pattern.matcher(text);
        return m.matches();
    }

    /**
     * 匹配帳號類型是否正確(只能輸入大小寫字母和數字,最大不超過20個字符)
     *
     * @param str 帳號
     * @return true= 符合 false=不符合
     */
    public static boolean isAccount(String str) {
        String format = "[a-zA-Z0-9]{0,20}";
        return isMatches(str, format);
    }

    /**
     * 匹配金額是否符合要求(99999999.99)
     *
     * @param money 金額字符串
     * @return true= 符合 false=不符合
     */
    public static boolean isMoney(String money) {
        String regex = "(^[1-9][0-9]{0,7}(\\.[0-9]{0,2})?)|(^0(\\.[0-9]{0,2})?)";
        return isMatches(money, regex);
    }
}

通過以上兩個類就可以對用戶的輸入進行實時限制了。

使用方法很簡單,給需要限制的EditText添加addTextChangedListener()方法,傳入ExamineTextWatcher對象

mEditText.addTextChangedListener(new ExamineTextWatcher(ExamineTextWatcher.TYPE_ACCOUNT, mEditText));

需要添加其它限制條件時,在ValidateUtil類裏添加限制條件,然後在ExamineTextWatcher類裏配置好相應的驗證類型標識,最後在onTextChanged()方法中調用對應的驗證條件


Demo源碼:傳送門


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