一般我們在限制用戶輸入的時候,都是要等到用戶在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()方法中調用對應的驗證條件。