在android開發中,經常會碰到edittext中特殊字元過濾和字元長度限制同時要求的問題,由於android不同版本之間的相容問題,以及各種手機支援情況不同,因此,經常會出現一些裝置上面不相容問題。為瞭解決這個問題,這裡經過實踐總結,給出一個最優的方案:
首先,對於字元長度的限制我們可以使用3種方法,如下:
1,使用EditText的setFilter方法實現,代碼如下:
定義EditText對象mEditText;
字元限制長度int MAX_TEXT_INPUT_LENGTH;
mEditText.setFilters(new InputFilter[]{new InputFilter.LengthFilter(MAX_TEXT_INPUT_LENGTH)});
這種方法只能限制固定長度的字元數,也就是說MAX_TEXT_INPUT_LENGTH必須是一個定值。
2, 同樣是使用setFilters方法,動態改變限制的字元長度:
int mMaxLenth = 20;//mMaxLenth可以動態改變
InputFilter[] FilterArray = new InputFilter[1];
FilterArray[0] = new InputFilter() {
@Override
public CharSequence filter (CharSequence source, int start, int end,
Spanned dest, int dstart, int dend){
boolean bInvlid = false;
int sourceLen = getCharacterNum(source.toString());
int destLen = getCharacterNum(dest.toString());
if (sourceLen + destLen > mMaxLenth) {
return ""; }
return source;
}
};
mEditText.setFilters(FilterArray);
3使用EditText的addTextChangedListener監聽事件實現:
mEditText.addTextChangedListener(new TextWatcher() {
private int cou = 0;
int selectionEnd = 0;
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
cou = before + count;
String editable = mEditText.getText().toString();
mEditText.setText(editable);
}
mEditText.setSelection(mEditText.length());
cou = mEditText.length();
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void afterTextChanged(Editable s) {
if (cou > mMaxLenth) {
selectionEnd = mEditText.getSelectionEnd();
s.delete(mMaxLenth, selectionEnd);
}
}
});
對於以上三種方法,通過在不同手機上測試,發現如下問題:
如果使用1,2兩種方法,在android 4.0以下的版本中,對於三星鍵盤英文IME,會出現輸入框上下跳動問題,比如三星S1等,而對於4.0以上版本的手機,同樣是三星鍵盤英文IME,會出現輸入字元錯誤,比如:三星NOTE 2上面在輸入框內會莫名的多出許多字元。
對於第3種方法,則效能相對穩定。
對於字元過濾,同理,如果我們使用setFilters方法實現,那麼,依然會出現輸入框跳動和莫名多出許多字元的問題。
經過三星,LG,Google等各種品牌手機的測試,最後給出一種最優的解決方案,即,在EditText的addTextChangedListener監聽事件中實現字元過濾和長度限制:
// 設定過濾字元函數(過濾掉我們不需要的字元)
public
static String stringFilter(String str)throws PatternSyntaxException{
String regEx =
"[/\\:*?<>|\"\n\t]";
Pattern p = Pattern.compile(regEx);
Matcher m = p.matcher(str);
return m.replaceAll("");
}
int mMaxLenth = 50;
mEditText.addTextChangedListener(new TextWatcher() {
private
int cou = 0;
int
selectionEnd = 0;
@Override
public
void onTextChanged(CharSequence s,
int start, int before,
int count) {
cou = before + count;
String editable =
mEditText.getText().toString();
String str =
stringFilter(editable);
if (!editable.equals(str)) {
mEditText.setText(str);
}
mEditText.setSelection(mEditText.length());
cou =
mEditText.length();
}
@Override
public
void beforeTextChanged(CharSequence s,
int start, int count,
int after) {
}
@Override
public
void afterTextChanged(Editable s) {
if (cou >
mMaxLenth) {
selectionEnd =
mEditText.getSelectionEnd();
s.delete(mMaxLenth,
selectionEnd);
if(androidVersion.charAt(0)>='4')
{
mEditText.setText(s.toString());
}
}
}
};