/**
* 輸入最大值限制
*/
class InputFilterValue(var context: Context, private var mMax: Int, var showToast: Boolean = true, var toast: String = "最大可輸入${mMax}") : InputFilter {
override fun filter(source: CharSequence?, start: Int, end: Int, dest: Spanned?, dstart: Int, dend: Int): CharSequence? {
val plus = dest.toString().plus(source)
if (TextUtils.isEmpty(plus)) return null
return try {
//mother fucker 這里要try catch一下
//場景 : plus為非int類型块攒,會導(dǎo)致numberFormatException
//即使xml文件中設(shè)置了digits為0-9励稳,但因為我們在代碼中設(shè)置了inputFilterValue的過濾器佃乘,導(dǎo)致
//原本digits的digitKeyListener過濾器的優(yōu)先級在inputFilterValue的后面了,所以用戶此時還是可以輸入除了digits之外的內(nèi)容的
when {
plus.toInt() > mMax -> {
if (showToast) ToastUtil.showCenter(context, toast)
""
}
else -> null
}
} catch (e: NumberFormatException) {
null
}
}
}
使用
InputFilter[] filters = editText.getFilters();
InputFilter[] newFilters = new InputFilter[filters.length + 1];
System.arraycopy(filters, 0, newFilters, 0, filters.length);
newFilters[filters.length] = new InputFilterValue(...)
editText.setFilters(newFilters);
這里要注意的是驹尼,我們需要在自定義的inputFilter中try catch
一下趣避,以為我們?nèi)绻苯影演斎氲闹?code>toInt的話是會有問題的。
有些同學(xué)可能想了新翎,我xml文件中已經(jīng)設(shè)置了digits
為0-9
了啊程帕,為什么toInt
還會有問題呢住练,難道此時ediText還可以輸入別的值不成?那我設(shè)置的digits
豈不是無效了愁拭?
這里我們看下editText.setFilters(newFilters)
的源碼處理:
public void setFilters(InputFilter[] filters) {
if (filters == null) {
throw new IllegalArgumentException();
}
mFilters = filters;
if (mText instanceof Editable) {
setFilters((Editable) mText, filters);
}
}
private void setFilters(Editable e, InputFilter[] filters) {
if (mEditor != null) {
final boolean undoFilter = mEditor.mUndoInputFilter != null;
final boolean keyFilter = mEditor.mKeyListener instanceof InputFilter;
int num = 0;
if (undoFilter) num++;
if (keyFilter) num++;
if (num > 0) {
InputFilter[] nf = new InputFilter[filters.length + num];
System.arraycopy(filters, 0, nf, 0, filters.length);
num = 0;
if (undoFilter) {
nf[filters.length] = mEditor.mUndoInputFilter;
num++;
}
if (keyFilter) {
nf[filters.length + num] = (InputFilter) mEditor.mKeyListener;
}
e.setFilters(nf);
return;
}
}
e.setFilters(filters);
}
通過源碼我們可以發(fā)現(xiàn)讲逛,我們再重新設(shè)置inputFilter
時,系統(tǒng)是會把我們設(shè)置的digits
重新copy過來的岭埠,但這里有個問題就是盏混,digits
的優(yōu)先級被降低了,我們再鍵盤輸入的時候就會導(dǎo)致先執(zhí)行了我們自定義的inputFilter
.這里我們可以看下鍵盤輸入最終對輸入內(nèi)容的處理:
public SpannableStringBuilder replace(final int start, final int end,
CharSequence tb, int tbstart, int tbend) {
checkRange("replace", start, end);
int filtercount = mFilters.length;
for (int i = 0; i < filtercount; i++) {
CharSequence repl = mFilters[i].filter(tb, tbstart, tbend, this, start, end);
if (repl != null) {
tb = repl;
tbstart = 0;
tbend = repl.length();
}
}
....
}
可以看到這里最后調(diào)用的就是我們editText
設(shè)置的inputFilter
惜论,這兒因為我們上面setInputFilter
導(dǎo)致digits
的優(yōu)先級變低,所以用戶此時輸入的內(nèi)容是沒有先受digits
的限制的许赃,而是先受限于我們自定義的inputFilter
,所以我們在上面的自定義的inputFilterValue中需要try catch一下.